package com.xjrsoft.module.buildCode.grant;

import cn.hutool.core.io.IoUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.xjrsoft.core.tool.utils.CollectionUtil;
import com.xjrsoft.core.tool.utils.JsonFormatUtil;
import com.xjrsoft.core.tool.utils.StringPool;
import com.xjrsoft.core.tool.utils.StringUtil;
import com.xjrsoft.module.app.entity.XjrAppFunction;
import com.xjrsoft.module.buildCode.dto.*;
import com.xjrsoft.module.buildCode.props.GlobalConfigProperties;
import com.xjrsoft.module.form.constant.FormConstants;
import io.swagger.models.auth.In;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.charset.Charset;
import java.util.*;
import java.util.stream.Collectors;

public class AppViewCodeHelper {

    public static String genListViewCode(String tbPk, ColDataDto colModel, List<QueryDataDto> queryModels, List<Map<String, Object>> formFieldList, BaseInfoDto baseModel) {
        StringBuilder code = new StringBuilder();
        String importStr = "";

        code.append("<template>\r\n");
        code.append("    <view class=\"page\" :style=\"[{ paddingTop: pagePaddingTop + 'px'}]\">\r\n");

        /* 顶部开始 */
        code.append("        <view class=\"cu-bar bg-white text-center fixed grid col-2 border-bottom\" :style=\"[{ top: CustomBar + 'px'}]\">\r\n");
        code.append("           <view @click.stop=\"showModal\" data-target=\"sortModal\">\r\n");
        code.append("               <text class=\"s15\">排序</text>\r\n");
        code.append("               <text class=\"cuIcon-sort\"></text>\r\n");
        code.append("           </view>\r\n");
        code.append("           <view @click.stop=\"showModal\" data-target=\"filterModal\">\r\n");
        code.append("               <text class=\"s15\">筛选</text>\r\n");
        code.append("               <text class=\"cuIcon-sort\"></text>\r\n");
        code.append("           </view>\r\n");
        code.append("        </view>\r\n");
        /* 顶部结束 */

        /* 列表开始 */
        code.append("        <view class=\"cu-list menu-avatar\">\r\n");
        code.append("           <view class=\"bg-white padding margin-sm radius-xs\" v-for=\"(item, index) in dataList\" :key=\"index\">\r\n");
        code.append("               <view class=\"content text-gray \">\r\n");
        code.append("                   <view>\r\n");
        for(Map<String, Object> col : colModel.getColumnList()) {
            String fieldName = MapUtils.getString(col, FormConstants.BIND_COLUMN);
            Map<String, Object> field = findFieldConfig(formFieldList, fieldName);
            Map<String, Object> fieldConfig = MapUtils.getMap(field, FormConstants.CONFIG);
            String type = MapUtils.getString(fieldConfig, "tag");
            code.append("                       <view style=\"line-height: 48upx;\" v-if=\"hasColumnPermission('" + fieldName + "')\">\r\n");
            code.append("                           <text class=\"con-label\" style=\"font:normal 12px/24px arial;font-size: 24upx;color: #999;\">" + MapUtils.getString(fieldConfig, "label") + "</text><text>：</text>\r\n");
            if (StringUtil.equalsIgnoreCase(type, "el-image")) {
                code.append("                           <view v-for=\"it in item." + fieldName + "ImgList\" :key=\"it.F_Id\" class=\"imgListPic\" @click=\"previewImg(it.url)\">\r\n");
                code.append("                       	      <image :src=\"it.url\" mode=\"aspectFill\"></image>\r\n");
                code.append("                           </view>\r\n");
                code.append("                       </view>\r\n");
            } else if (StringUtil.equalsIgnoreCase(type, "upload")) {
                code.append("                           <view v-for=\"(it, index) in item." + fieldName + "FileList\" :key=\"index\" class=\"fileListbox\">\r\n");
                code.append("                               <!-- #ifdef H5 -->\r\n");
                code.append("                               <a :href=\"baseURL +it.url\" target=\"blank\">{{ it.F_FileName }}</a>\r\n");
                code.append("                               <!-- #endif -->\r\n");
                code.append("                               <!-- #ifdef APP-PLUS -->\r\n");
                code.append("                               <view @click=\"downLoad(baseUrl + item.url)\">{{ it.F_FileName }}</view>\r\n");
                code.append("                               <!-- #endif -->\r\n");
                code.append("                           </view>\r\n");
                code.append("                       </view>\r\n");
            } else {
                code.append("                           <view class=\"con-value\" style=\"font:normal 12px/24px arial;font-size: 24upx; color: #999;text-align: left;\">\r\n");
                String avueType = MapUtils.getString(fieldConfig, "avueType");
                if (StringUtil.equalsIgnoreCase(type, "tinymce")) {
                    code.append("                               <view class=\"listItemOverflow\">\r\n");
                    code.append("                                   <rich-text :nodes=\"item." + fieldName + "\"></rich-text>\r\n");
                    code.append("                               </view>\r\n");
                } else if (StringUtil.equalsIgnoreCase(avueType, "switch")){
                    String activeValue = MapUtils.getString(field, "active-value");
                    code.append("                               <switch :class=\"item." + fieldName + "==" + activeValue + "?'checked':''\" :checked=\"item." + fieldName + "==" + activeValue + "\" class=\"small\" disabled></switch>\r\n");
                } else {
                    code.append("                               <text>{{item." + fieldName + "}}</text>\r\n");
                }
                code.append("                            </view>\r\n");
                code.append("                       </view>\r\n");
            }
        }

        importStr += "import { setting } from '@/appsetting.js'\r\n";

        code.append("                   </view>\r\n");
        code.append("               </view>\r\n");

        code.append("               <view class=\"flex align-center justify-end text-blue padding-top-sm cu-list grid col-4\">\r\n");
        code.append("                   <view class=\"text-right\" @click=\"tapToForm(item." + tbPk + ")\" v-if=\"hasButtonPermission('modify')\"><text class=\"cuIcon-writefill margin-right-xs\"></text> 编辑</view>\r\n");
        code.append("                   <view class=\"text-right\" @click=\"tapToDelete(item." + tbPk + ")\" v-if=\"hasButtonPermission('delete')\"><text class=\"fa fa-trash margin-right-xs\"></text> 删除</view>\r\n");
        code.append("                   <view class=\"text-right\" @click=\"tapToDetail(item." + tbPk + ",index)\" v-if=\"hasButtonPermission('view')\">查看 <text class=\"cuIcon-right\"></text></view>\r\n");
        code.append("               </view>\r\n");

        code.append("           </view>\r\n");
        code.append("           <image :src=\"require('@/static/images/nodata.png')\" v-if=\"dataList.length<=0\" mode=\"widthFix\" style=\"margin: 100px auto 0;display: block;width: 50%;\"></image>\r\n");
        code.append("        </view>\r\n");
        /* 列表结束 */


        /* 排序开始 */
        code.append("        <view class=\"cu-modal bottom-modal\" :class=\"modalName == 'sortModal' ? 'show' : ''\" :style=\"[{ top: pagePaddingTop + CustomBar + 'px'}]\">\r\n");

        code.append("            <view class=\"cu-dialog\">\r\n");
        code.append("                <view class=\"contentBox sort\">\r\n");
        code.append("                  <view class=\"text-bold text-grey\">排序方式</view>\r\n");
        code.append("                    <view class=\"text-grey margin-top-xs margin-bottom\">\r\n");
        code.append("                       <view class=\"divider_bottom padding-top-sm padding-bottom-sm padding-left-sm flex justify-between\" @click.stop=\"sortTypeSelect\" data-target=\"asc\">\r\n");
        code.append("                           <view>正序排序</view>\r\n");
        code.append("                           <view class=\"cuIcon-check text-bold text-blue\" :class=\"pageParam.order == 'asc' ? 'show' : 'hide'\"></view>\r\n");
        code.append("                       </view>\r\n");
        code.append("                       <view class=\"divider_bottom padding-top-sm padding-bottom-sm padding-left-sm flex justify-between\" @click.stop=\"sortTypeSelect\" data-target=\"desc\">\r\n");
        code.append("                           <view>倒序排序</view>\r\n");
        code.append("                           <view class=\"cuIcon-check text-bold text-blue\" :class=\"pageParam.order == 'desc' ? 'show' : 'hide'\"></view>\r\n");
        code.append("                       </view>\r\n");
        code.append("                    </view>\r\n");
        code.append("                   <view class=\"text-bold text-grey\">排序属性</view>\r\n");
        code.append("                   <view class=\"text-grey margin-top-xs margin-bottom\">\r\n");


        for(QueryDataDto queryModel : queryModels)
        {

            code.append("                       <view class=\"divider_bottom padding-top-sm padding-bottom-sm padding-left-sm flex justify-between\" @click.stop=\"sortSelect\" data-target=\""+queryModel.getField()+"\">\r\n");
            code.append("                           <view>"+queryModel.getName()+"</view>\r\n");
            code.append("                           <view class=\"cuIcon-check text-bold text-blue\" :class=\"pageParam.orderfield == '"+queryModel.getField()+"' ? 'show' : 'hide'\"></view>\r\n");
            code.append("                       </view>\r\n");

        }

        code.append("                   </view>\r\n");
        code.append("                </view>\r\n");
        code.append("                <view class=\"grid col-2 btnbox border-top\">\r\n");
        code.append("                    <view class=\"line-blue\" @tap=\"reset\">重置</view>\r\n");
        code.append("                    <view class=\"bg-blue\" @tap=\"confirm\">确定</view>\r\n");
        code.append("                </view>\r\n");
        code.append("           </view>\r\n");
        code.append("        </view>\r\n");
        /* 排序结束 */


        /* 筛选开始 */
        code.append("        <view class=\"cu-modal bottom-modal\" :class=\"modalName == 'filterModal' ? 'show' : ''\" :style=\"[{ top: pagePaddingTop + CustomBar + 'px'}]\">\r\n");
        code.append("            <view class=\"cu-dialog bg-white\">\r\n");
        code.append("                <view class=\"contentBox\">\r\n");


        String dataStr = "";
        String componentStr = "";
        String timeSearchStr = StringPool.EMPTY;
        for(QueryDataDto queryModel : queryModels) {
            //找到表单设定里面的参数
            String queryFieldName = StringUtil.equalsIgnoreCase(queryModel.getSearchtype(), "data") ? queryModel.getField() : queryModel.getDateField();
            Map<String, Object> field = findFieldConfig(formFieldList, queryFieldName);
            Map<String, Object> fieldConfig = MapUtils.getMap(field, FormConstants.CONFIG);


            if (fieldConfig == null) {
                break;
            }
            // 数据源数据字典处理
            String dataType = MapUtils.getString(fieldConfig, "dataType");
            String dataSource = getDataSourceByType(dataType);
            String dataItem = getDataItem(fieldConfig, dataSource);
            String saveField = MapUtils.getString(fieldConfig, "saveField");
            String showField = MapUtils.getString(fieldConfig, "showField");
            String avueType = MapUtils.getString(fieldConfig, FormConstants.FORM_COMPONENT_TYPE, StringPool.EMPTY);
            if (StringUtil.isEmpty(avueType) || StringUtil.equalsIgnoreCase(avueType, "information-body")) {
                String fieldType = MapUtils.getString(field, FormConstants.FIELD_TYPE, StringPool.EMPTY);
                if (StringUtil.equalsIgnoreCase(fieldType, "info")) {
                    fieldType = MapUtils.getString(field, "infoType");
                    if (StringUtil.equalsIgnoreCase(fieldType, "date")) {
                        field.put("type", "datetime");
                    }
                }
                avueType = fieldType;
            }
            String apiConfigCode = StringPool.EMPTY;
            if (StringUtil.equalsIgnoreCase(dataType, "dataApi")) {
                apiConfigCode = ",apiConfig: " + JSONObject.toJSONString(fieldConfig.get("apiConfig"));
            }
            switch(StringUtils.lowerCase(avueType)) {
                case "time":
                    dataStr += queryFieldName + "DateConfig : { 'title' : '" + queryModel.getName() + "', separator:'至', placeholder:'选择时间',field:\"" + queryFieldName + "\" },";
                    if (!StringUtils.contains(importStr, "TimeRange.vue")) {
                        importStr += "import xjrTimeRange from \"@/components/Filter/Date/TimeRange.vue\" \r\n";
                        componentStr += "xjrTimeRange, \r\n";
                    }
                    code.append("                        <xjr-time-range :timeRangeConfig=\"" + queryFieldName + "DateConfig\" @clearTime=\"clearTime\"  v-model=\"pageParam['" + queryFieldName + "']\"></xjr-time-range>\r\n");
                    timeSearchStr += String.format("            const %1$s_daterange =  this.pageParam[\"%1$s\"] \r\n", queryFieldName);
                    timeSearchStr += String.format("            this.pageParam[\"%1$s_Start\"] = %1$s_daterange[0] \r\n", queryFieldName);
                    timeSearchStr += String.format("            this.pageParam[\"%1$s_End\"] = %1$s_daterange[1] \r\n", queryFieldName);
                    break;
                case "date":
                case "datetime":
                    String type = MapUtils.getString(field, "type");
                    if (StringUtil.equalsIgnoreCase(type, "datetime")) {
                        if (!StringUtils.contains(importStr, "/Date.vue")) {
                            importStr += "import xjrDate from \"@/components/Filter/Date/Date.vue\" \r\n";
                            componentStr += "xjrDate, \r\n";
                        }
                        code.append("                        <xjr-date :dateConfig=\"" + queryFieldName + "DateConfig\" @getTime=\"getTime\" @clearTime=\"clearTime\"  v-model=\"pageParam['" + queryFieldName + "']\"></xjr-date>\r\n");
                        dataStr += queryFieldName + "DateConfig : { 'title' : '" + queryModel.getName() + "', separator: '至', placeholder: '" + field.get("placeholder") + "',field:\"" + queryFieldName + "\" },";
                    } else {
                        if (!StringUtils.contains(importStr, "rangeDate.vue")) {
                            importStr += "import xjrRangeDate from \"@/components/Filter/Date/rangeDate.vue\" \r\n";
                            componentStr += "xjrRangeDate, \r\n";
                        }
                        code.append("                        <xjr-range-date :dateConfig=\"" + queryFieldName + "DateConfig\" @getTime=\"getTime\" @clearTime=\"clearTime\"  v-model=\"pageParam['" + queryFieldName + "']\"></xjr-range-date>\r\n");
                        dataStr += queryFieldName + "DateConfig : { 'title' : '" + queryModel.getName() + "', format: '" + type + "',field:\"" + queryFieldName + "\"},";
                    }

                    timeSearchStr += String.format("            const %1$s_daterange =  this.pageParam[\"%1$s\"] \r\n", queryFieldName);
                    timeSearchStr += String.format("            this.pageParam[\"%1$s_Start\"] = %1$s_daterange[0] \r\n", queryFieldName);
                    timeSearchStr += String.format("            this.pageParam[\"%1$s_End\"] = %1$s_daterange[1] \r\n", queryFieldName);
                    break;
                case "input-tip":
                    dataStr += queryFieldName + "InputConfig : { 'title' : '" + queryModel.getName() + "','placeholder' : '请输入" + queryModel.getName() + "' },";
                    if (!StringUtils.contains(importStr, "Input.vue")) {
                        importStr += "import xjrInput from \"@/components/Filter/Input/Input.vue\" \r\n";
                        componentStr += "xjrInput, \r\n";
                    }
                    code.append("                        <xjr-input :inputConfig=\"" + queryFieldName + "InputConfig\" v-model=\"pageParam['" + queryFieldName + "']\"></xjr-input>\r\n");
                    break;
                case "radio":
                    //找到表单设定里面的参数
                    dataStr += queryFieldName + "SingleConfig : { 'title' : '" + queryModel.getName() + "','placeholder' : '请选择" + queryModel.getName() + "','dataSource' : '" + dataSource + "', 'dataItem':'" + dataItem + "','saveField' : '" + saveField + "','showField':'" + showField + "'" + apiConfigCode + " },";
                    if (!StringUtils.contains(importStr, "Single.vue")) {
                        importStr += "import xjrSingle from \"@/components/Filter/Single/Single.vue\" \r\n";
                        componentStr += "xjrSingle, \r\n";
                    }
                    code.append("                        <xjr-single :singleConfig=\"" + queryFieldName + "SingleConfig\" v-model=\"pageParam['" + queryFieldName + "']\"></xjr-single>\r\n");
                    break;
                case "mutiple-popup":
                case "checkbox":
                    //找到表单设定里面的参数
                    dataStr += queryFieldName + "MultipleConfig : { 'title' : '" + queryModel.getName() + "','placeholder' : '请选择" + queryModel.getName() + "','dataSource' : '" + dataSource + "', 'dataItem':'" + dataItem + "','saveField' : '" + saveField + "','showField':'" + showField + "'" + apiConfigCode + " },";
                    if (!StringUtils.contains(importStr, "Multiple.vue")) {
                        importStr += "import xjrMultiple from \"@/components/Filter/Multiple/Multiple.vue\" \r\n";
                        componentStr += "xjrMultiple, \r\n";
                    }
                    code.append("                        <xjr-multiple :multipleConfig=\"" + queryFieldName + "MultipleConfig\" v-model=\"pageParam['" + queryFieldName + "']\"></xjr-multiple>\r\n");
                    break;
                case "asso-popup":
                case "asso-select":
                case "select":
                    //找到表单设定里面的参数
                    dataStr += queryFieldName + "SelectConfig : { 'title' : '" + queryModel.getName() + "','placeholder' : '请选择" + queryModel.getName() + "','dataSource' : '" + dataSource + "', 'dataItem':'" + dataItem + "','saveField' : '" + saveField + "','showField':'" + showField + "'" + apiConfigCode + " },";
                    if (!StringUtils.contains(importStr, "Picker.vue")) {
                        importStr += "import xjrSelect from \"@/components/Filter/Picker/Picker.vue\" \r\n";
                        componentStr += "xjrSelect, \r\n";
                    }
                    code.append("                        <xjr-select :selectConfig=\"" + queryFieldName + "SelectConfig\" v-model=\"pageParam['" + queryFieldName + "']\"></xjr-select>\r\n");
                    break;
                case "user":
                    dataStr += queryFieldName + "Config : { 'title' : '" + queryModel.getName() + "','placeholder' : '" + MapUtils.getString(field, "placeholder") + "' },";
                    if (!StringUtils.contains(importStr, "User.vue")) {
                        importStr += "import xjrUser from \"@/components/Filter/Organization/User.vue\" \r\n";
                        componentStr += "xjrUser, \r\n";
                    }
                    code.append("                        <xjr-user :config=\"" + queryFieldName + "Config\" v-model=\"pageParam['" + queryFieldName + "']\"></xjr-user>\r\n");
                    break;
                case "department":
                    dataStr += queryFieldName + "Config : { 'title' : '" + queryModel.getName() + "','placeholder' : '" + MapUtils.getString(field, "placeholder") + "' },";
                    if (!StringUtils.contains(importStr, "Department.vue")) {
                        importStr += "import xjrDepartment from \"@/components/Filter/Organization/Department.vue\" \r\n";
                        componentStr += "xjrDepartment, \r\n";
                    }
                    code.append("                        <xjr-department :config=\"" + queryFieldName + "Config\" v-model=\"pageParam['" + queryFieldName + "']\"></xjr-department>\r\n");
                    break;
                case "company":
                    dataStr += queryFieldName + "Config : { 'title' : '" + queryModel.getName() + "','placeholder' : '" + MapUtils.getString(field, "placeholder") + "' },";
                    if (!StringUtils.contains(importStr, "Company.vue")) {
                        importStr += "import xjrCompany from \"@/components/Filter/Organization/Company.vue\" \r\n";
                        componentStr += "xjrCompany, \r\n";
                    }
                    code.append("                        <xjr-company :config=\"" + queryFieldName + "Config\" v-model=\"pageParam['" + queryFieldName + "']\"></xjr-company>\r\n");
                    break;
                case "cascader":
                    dataStr += queryFieldName + "Config : { 'title':'" + queryModel.getName() + "',placeholder : '请选择" + queryModel.getName() + "',settings:" + JSON.toJSONString(MapUtils.getObject(fieldConfig, "settings")) + ",separator:'" + MapUtils.getString(field, "separator") + "',showAllLevels:" + MapUtils.getBoolean(field,"show-all-levels") + ", checkStrictly:" + MapUtils.getBoolean(field, "checkStrictly", false) + "},";
                    if (!StringUtils.contains(importStr, "cascaderAny.vue")) {
                        importStr += "import xjrCascader from \"@/components/Filter/cascader/cascaderAny.vue\" \r\n";
                        componentStr += "xjrCascader, \r\n";
                    }
                    code.append("                        <xjr-cascader :inputConfig=\""+ queryFieldName + "Config\" v-model=\"pageParam['"+ queryFieldName + "']\"></xjr-cascader>\r\n");
                    break;
                case "color":
                    dataStr += queryFieldName + "InputConfig : { 'title':'" + queryModel.getName() + "',placeholder : '请选择" + queryModel.getName() + "'},";
                    if (!StringUtils.contains(importStr, "ColorPicker.vue")) {
                        importStr += "import xjrColorPicker from \"@/components/Filter/color-picker/ColorPicker.vue\" \r\n";
                        componentStr += "xjrColorPicker, \r\n";
                    }
                    code.append("                        <xjr-color-picker :colorConfig=\"" + queryFieldName + "InputConfig\" v-model=\"pageParam['" + queryFieldName + "']\"></xjr-color-picker>\r\n");
                    break;
                case "select-area":
                    dataStr += queryFieldName + "InputConfig : { 'title':'" + queryModel.getName() + "',placeholder : '请选择" + queryModel.getName() + "'},";
                    if (!StringUtils.contains(importStr, "Area.vue")) {
                        importStr += "import xjrArea from \"@/components/Filter/Area/Area.vue\" \r\n";
                        componentStr += "xjrArea, \r\n";
                    }
                    code.append("                        <xjr-area v-model=\"pageParam['" + queryFieldName + "']\" :config=\"" + queryFieldName + "InputConfig\"></xjr-area>\r\n");
                    break;
                case "switch":
                    dataStr += queryFieldName + "Config : { 'title':'" + queryModel.getName() + "',placeholder : '请选择" + queryModel.getName() + "',activeValue:" + MapUtils.getInteger(field, "active-value") + ", inactiveValue:" + MapUtils.getInteger(field, "inactive-value") + "},";
                    if (!StringUtils.contains(importStr, "switch.vue")) {
                        importStr += "import xjrSwitch from \"@/components/Filter/Picker/switch.vue\" \r\n";
                        componentStr += "xjrSwitch, \r\n";
                    }
                    code.append("                       <xjr-switch :selectConfig=\"" + queryFieldName + "Config\" v-model=\"pageParam['" + queryFieldName + "']\"></xjr-switch>\r\n");
                    break;
                default:
                    dataStr += queryFieldName + "InputConfig : { 'title' : '" + queryModel.getName() + "','placeholder' : '请输入" + queryModel.getName() + "' },";
                    if (!StringUtils.contains(importStr, "Input.vue")) {
                        importStr += "import xjrInput from \"@/components/Filter/Input/Input.vue\" \r\n";
                        componentStr += "xjrInput, \r\n";
                    }
                    code.append("                        <xjr-input :inputConfig=\"" + queryFieldName + "InputConfig\" v-model=\"pageParam['" + queryFieldName + "']\"></xjr-input>\r\n");
                    break;

            }

        }

        code.append("                </view>\r\n");
        code.append("                <view class=\"grid col-2 btnbox border-top\">\r\n");
        code.append("                    <view class=\"line-blue\" @tap=\"reset\">重置</view>\r\n");
        code.append("                    <view class=\"bg-blue\" @tap=\"confirm\">确定</view>\r\n");
        code.append("                </view>\r\n");
        code.append("           </view>\r\n");
        code.append("        </view>\r\n");
        /* 筛选结束 */

        code.append("    <view class=\"cuIcon-roundaddfill text-blue\" @click=\"tapToFormAdd()\" v-if=\"hasButtonPermission('add')\"></view>\r\n");
        code.append("    </view>\r\n");
        code.append("</template>\r\n\r\n");

        code.append("<script>\r\n");

        code.append(importStr);

        code.append("export default {\r\n");
        code.append("    data() {\r\n");
        code.append("        return {\r\n");
        code.append("            moduleid:[],\r\n");
        code.append("            formEncode:'" + baseModel.getName() + "',\r\n");
        code.append("            buttonPermission:[],\r\n");
        code.append("            columnPermission:[],\r\n");
        code.append("            baseURL:setting.baseURL,\r\n");
        code.append("            StatusBar: this.StatusBar,\r\n");
        code.append("            CustomBar: this.CustomBar,\r\n");
        code.append("            // #ifdef MP-WEIXIN\r\n");
        code.append("            CustomBar: 0,\r\n");
        code.append("            // #endif\r\n");
        code.append("            pagePaddingTop: this.pagePaddingTop,\r\n");
        code.append("            modalName: null,\r\n");
        code.append("            dataList:[],\r\n");
        code.append("            curID:'',\r\n");
        code.append("            controlType:'',\r\n");
        SortDataDto sortDataDto = colModel.getSortDataDto();
        code.append("            pageParam: { limit: 1,size: 15,order: '" + sortDataDto.getOrder() + "',orderfield: '" + sortDataDto.getSortField() + "' },\r\n");
        code.append("            listTotal: 0,\r\n");

        //放置各种组件配置
        code.append(dataStr);
        //放置各种组件配置结束

        code.append("        }\r\n");
        code.append("    },\r\n");


        code.append("   onLoad(opt) {\r\n");
        code.append("       this.moduleid = opt.moduleid;\r\n");
        code.append("   },\r\n");

        code.append("    onShow() {\r\n");
        code.append("        if(this.controlType==\"add\"||this.controlType==\"\"){\r\n");
        code.append("            this.pageParam.limit = 1;\r\n");
        code.append("            this.dataList = []\r\n");
        code.append("        }\r\n");
        code.append("        if(this.controlType==\"look\") return;\r\n");
        code.append("        this.initPermissions();\r\n");
        code.append("        this.getData()\r\n");
        code.append("    },\r\n");

        code.append("    onReachBottom() {\r\n");
        code.append("        if (this.pageParam.limit < this.listTotal) {\r\n");
        code.append("            this.pageParam.limit += 1;\r\n");
        code.append("            this.getData();\r\n");
        code.append("        }else{\r\n");
        code.append("            uni.showToast({\r\n");
        code.append("                    title: '没有更多数据了~',\r\n");
        code.append("                    icon:'none',\r\n");
        code.append("                    duration: 2000,\r\n");
        code.append("                    position:'bottom'\r\n");
        code.append("            });\r\n");
        code.append("        }\r\n");
        code.append("    },\r\n");

        code.append("    methods: {\r\n");
        code.append("        hasButtonPermission(btn){\r\n");
        code.append("            let btnName = this.formEncode+':'+btn;\r\n");
        code.append("            return this.buttonPermissions.includes(btnName);\r\n");
        code.append("        },\r\n");
        code.append("        hasColumnPermission(field){\r\n");
        code.append("            return this.columnPermissions.includes(field);\r\n");
        code.append("        },\r\n");
        code.append("        initPermissions(){\r\n");
        code.append("            let self = this;\r\n");
        code.append("            uni.getStorage({\r\n");
        code.append("                    key: 'permissions',\r\n");
        code.append("                    success: function (res) {\r\n");
        code.append("                    const userPermission = new Map(res.data);\r\n");
        code.append("                if(userPermission.size>0&&userPermission.has(self.moduleid)){\r\n");
        code.append("                    let value = userPermission.get(self.moduleid);\r\n");
        code.append("                    if(value.buttons&&Array.isArray(value.buttons)){\r\n");
        code.append("                        if(Array.isArray(value.buttons)){\r\n");
        code.append("                            self.buttonPermissions  = value.buttons;\r\n");
        code.append("                        }\r\n");
        code.append("                    }\r\n");
        code.append("                    if(value.columns&&Array.isArray(value.columns)){\r\n");
        code.append("                        self.columnPermissions = value.columns;\r\n");
        code.append("                    }\r\n");
        code.append("                }\r\n");
        code.append("            }\r\n");
        code.append("            });\r\n");
        code.append("        },\r\n");
        code.append("        clearTime(data){\r\n");
        code.append("            this.pageParam[data + '_Start']=null;\r\n");
        code.append("            this.pageParam[data + '_End']=null\r\n");
        code.append("        },\r\n");
        code.append("        getTime(data) {\r\n");
        code.append("            let start = this.pageParam[data][0]\r\n");
        code.append("            let end = this.pageParam[data][1]\r\n");
        code.append("            this.$set(this.pageParam, data + '_Start', start);\r\n");
        code.append("            this.$set(this.pageParam, data + '_End', end);\r\n");
        code.append("        },\r\n");
        code.append("        downLoad(url) {\r\n");
        code.append("            uni.request({\r\n");
        code.append("                    url: url,\r\n");
        code.append("                    method: 'HEAD',\r\n");
        code.append("                    success: function(response) {\r\n");
        code.append("                let header = response.header\r\n");
        code.append("                let filename = ''\r\n");
        code.append("               if (header['Content-Disposition'] && (header['Content-Disposition'].indexOf(\"filename*=UTF-8''\") >= 0)) {\r\n");
        code.append("                   let headerArr = header['Content-Disposition'].split(\"filename*=UTF-8''\")\r\n");
        code.append("                    filename = headerArr[1]\r\n");
        code.append("                } else {\r\n");
        code.append("                    let headerArr = header['Content-Disposition'].split(\"filename=\")\r\n");
        code.append("                    filename = headerArr[1]\r\n");
        code.append("                }\r\n");
        code.append("                let dtask = plus.downloader.createDownload(url, {\r\n");
        code.append("                        filename: \"_downloads/\" + decodeURIComponent(filename)\r\n");
        code.append("           }, function(download, status) {\r\n");
        code.append("                    if (status == 200) {\r\n");
        code.append("                        plus.runtime.openFile(download.filename)\r\n");
        code.append("                    } else {\r\n");
        code.append("                        //下载失败\r\n");
        code.append("                        plus.downloader.clear(); //清除下载任务\r\n");
        code.append("                    }\r\n");
        code.append("                })\r\n");
        code.append("                dtask.start()\r\n");
        code.append("            }\r\n");
        code.append("        })\r\n");
        code.append("        },\r\n");
        code.append("        navBack(obj) {\r\n");
        code.append("            if(obj." + tbPk + ") this.curID=obj." + tbPk + ";\r\n");
        code.append("        },\r\n");
        code.append("        tapToForm(id) {\r\n");
        code.append("            this.controlType='edit';\r\n");
        code.append("            this.curID=id;\r\n");
        code.append("            uni.navigateTo({\r\n");
        code.append("                url: \"./" + baseModel.getName() + "Form?keyValue=\" + id + \"&type=edit\" + \"&moduleid=\"+this.moduleid \r\n");
        code.append("            })\r\n");
        code.append("        },\r\n");
        code.append("        tapToFormAdd(id) {\r\n");
        code.append("        this.controlType='add';\r\n");
        code.append("            uni.navigateTo({\r\n");
        code.append("                url: \"./" + baseModel.getName() + "Form?type=edit\" + \"&moduleid=\"+this.moduleid \r\n");
        code.append("            })\r\n");
        code.append("        },\r\n");
        code.append("        tapToDetail(id) {\r\n");
        code.append("            this.controlType='look';\r\n");
        code.append("            uni.navigateTo({\r\n");
        code.append("                url: \"./" + baseModel.getName() + "Form?keyValue=\" + id + \"&type=look\" + \"&moduleid=\"+this.moduleid \r\n");
        code.append("            })\r\n");
        code.append("        },\r\n");
        code.append("        tapToDelete(id,index) {\r\n");
        code.append("            const that = this;\r\n");
        code.append("            uni.showModal({\r\n");
        code.append("                cancelText: '取消',\r\n");
        code.append("                confirmText: '确定',\r\n");
        code.append("                content: '是否确定删除此数据？',\r\n");
        code.append("                success: async (res) => {\r\n");
        code.append("                    if (res.confirm) {\r\n");
        code.append("                       uni.showLoading({title: '删除中',mask:true});\r\n");
        code.append("                       const { data } = await that.$http.request({\r\n");
        code.append("                           url: '/" + baseModel.getName().toLowerCase() + "/' + id,\r\n");
        code.append("                           method: 'DELETE'\r\n");
        code.append("                       });\r\n");
        code.append("                       let idx=this.dataList.findIndex(o=>{return o." + tbPk + "==id})\r\n");
        code.append("                       if(idx>=0){\r\n");
        code.append("                           this.dataList.splice(idx,1)\r\n");
        code.append("                       }\r\n");
        code.append("                       uni.hideLoading()\r\n");
        code.append("                    } else {\r\n");
        code.append("                        return;\r\n");
        code.append("                    }\r\n");
        code.append("                }\r\n");
        code.append("            });\r\n");
        code.append("        },\r\n");
        code.append("        showModal(e) {\r\n");
        code.append("            if (this.modalName == e.currentTarget.dataset.target)\r\n");
        code.append("               this.modalName = null;\r\n");
        code.append("            else\r\n");
        code.append("               this.modalName = e.currentTarget.dataset.target\r\n");
        code.append("        },\r\n");
        code.append("        confirm(e) {\r\n");
        code.append("            this.modalName = null;\r\n");
        code.append("            this.pageParam.limit=1;\r\n");
        code.append("            this.dataList=[]\r\n");
        code.append("            this.controlType='';\r\n");
        for(QueryDataDto queryModel : queryModels) {
            if (StringUtil.equalsIgnoreCase(queryModel.getType(), "datetime")) {
                String field = queryModel.getField();
                code.append("            if(this.pageParam['" + field + "']){\r\n");
                code.append("               this.pageParam['" + field + "_Start']=this.pageParam['" + field + "'][0];\r\n");
                code.append("               this.pageParam['" + field + "_End']=this.pageParam['" + field + "'][1];\r\n");
                code.append("            }\r\n");
            }
        }
        code.append("            this.getData();\r\n");
        code.append("        },\r\n");
        code.append("        reset(e) { \r\n");
        code.append("            for (let key in this.pageParam) {\r\n");
        code.append("               if (key == 'limit') \r\n");
        code.append("                   this.pageParam[key] = 1;\r\n");
        code.append("               else if (key == 'size') \r\n");
        code.append("                   this.pageParam[key] = 15;\r\n");
        code.append("               else\r\n");
        code.append("                   this.pageParam[key]=\"\";\r\n");
        code.append("            }\r\n");
        code.append("        },\r\n");
        code.append("        sortTypeSelect(e) {\r\n");
        code.append("            if (this.pageParam.order == e.currentTarget.dataset.target) {\r\n");
        code.append("               this.pageParam.order = '';\r\n");
        code.append("            } else {\r\n");
        code.append("               this.pageParam.order = e.currentTarget.dataset.target\r\n");
        code.append("            }\r\n");
        code.append("        },\r\n");
        code.append("        sortSelect(e) {\r\n");
        code.append("            if (this.pageParam.orderfield == e.currentTarget.dataset.target) {\r\n");
        code.append("               this.pageParam.orderfield = '';\r\n");
        code.append("            } else {\r\n");
        code.append("               this.pageParam.orderfield = e.currentTarget.dataset.target\r\n");
        code.append("            }\r\n");
        code.append("        },\r\n");
        code.append("        async getData(){\r\n");
        code.append("           const {\r\n");
        code.append("               data: {\r\n");
        code.append("                   Rows,\r\n");
        code.append("                   Total\r\n");
        code.append("               }\r\n");
        code.append("           } = await this.$http.request({\r\n");
        code.append("               url: '/" + baseModel.getName().toLowerCase() + "',\r\n");
        code.append("               method: 'get',\r\n");
        code.append("               data: this.pageParam,\r\n");
        code.append("               header:{ModuleId:this.moduleid}\r\n");
        code.append("           });\r\n");
        code.append("           if (this.controlType==\"edit\") {\r\n");
        code.append("                Rows.forEach(item=>{\r\n");
        for (Map<String, Object> column : colModel.getColumnList()) {
            String imgField = MapUtils.getString(column, FormConstants.BIND_COLUMN);
            Map<String, Object> field = findFieldConfig(formFieldList, imgField);
            Map<String, Object> fieldConfig = MapUtils.getMap(field, FormConstants.CONFIG);
            String type = MapUtils.getString(fieldConfig, "tag");
            if (StringUtil.equalsIgnoreCase(type, "el-image")) {
                code.append("                   this.getImgFun(item,item." + imgField + ",'" + imgField + "ImgList')\r\n");
            }
            if (StringUtil.equalsIgnoreCase(type, "el-upload")) {
                code.append("                   this.getImgFun(item,item." + imgField + ",'" + imgField + "FileList')\r\n");
            }
        }
        code.append("                })\r\n");
        code.append("                let temp=Rows.find(o => {\r\n");
        code.append("                    return o."+ tbPk +" == this.curID\r\n");
        code.append("                })\r\n");
        code.append("                let idx = this.dataList.findIndex(o => {\r\n");
        code.append("                    return o."+ tbPk +" == this.curID\r\n");
        code.append("                })\r\n");
        code.append("                if (idx >= 0) {\r\n");
        code.append("                    this.dataList.splice(idx, 1, temp)\r\n");
        code.append("                }\r\n");
        code.append("           } else {\r\n");
        code.append("                this.listTotal=Math.ceil(Total / this.pageParam.size);\r\n");
        code.append("                this.dataList = this.dataList.concat(Rows);\r\n");
        code.append("                this.dataList.forEach(item=>{\r\n");
        for (Map<String, Object> column : colModel.getColumnList()) {
            String imgField = MapUtils.getString(column, FormConstants.BIND_COLUMN);
            Map<String, Object> field = findFieldConfig(formFieldList, imgField);
            Map<String, Object> fieldConfig = MapUtils.getMap(field, FormConstants.CONFIG);
            String type = MapUtils.getString(fieldConfig, "tag");
            if (StringUtil.equalsIgnoreCase(type, "el-image")) {
                code.append("                   this.getImgFun(item,item." + imgField + ",'" + imgField + "ImgList')\r\n");
            }
            if (StringUtil.equalsIgnoreCase(type, "el-upload")) {
                code.append("                   this.getImgFun(item,item." + imgField + ",'" + imgField + "FileList')\r\n");
            }
        }
        code.append("                })\r\n");
        code.append("           }\r\n");
        code.append("        },\r\n");

        code.append("    async getImgFun(item, imgField, name){\r\n");
        code.append("       if (imgField) {\r\n");
        code.append("           if (imgField.indexOf(\"http\") < 0){\r\n");
        code.append("               const {\r\n");
        code.append("                   data\r\n");
        code.append("               }=await this.$http.request({\r\n");
        code.append("                   url: '/annexes-files/url/' + imgField,\r\n");
        code.append("                   method: 'get'\r\n");
        code.append("    	        })\r\n");
        code.append("               if ( data && data.length > 0) {\r\n");
        code.append("                   data.forEach(it=>{\r\n");
        code.append("                       it.url=this.baseURL+it.url;\r\n");
        code.append("                   })\r\n");
        code.append("                   this.$set(item, name, data)\r\n");
        code.append("               }\r\n");
        code.append("           } else {\r\n");
        code.append("                let arr=[{F_Id:new Date().getTime(),url:imgField}]\r\n");
        code.append("                this.$set(item, name, arr)\r\n");
        code.append("           }\r\n");
        code.append("       }\r\n");
        code.append("    },\r\n");
        code.append("    previewImg(url){\r\n");
        code.append("        let arr=[]\r\n");
        code.append("        arr.push(url)\r\n");
        code.append("        uni.previewImage({\r\n");
        code.append("                urls: arr,\r\n");
        code.append("                longPressActions: {\r\n");
        code.append("            itemList: ['发送给朋友', '保存图片', '收藏'],\r\n");
        code.append("            success: function(data) {\r\n");
        code.append("                //console.log('选中了第' + (data.tapIndex + 1) + '个按钮,第' + (data.index + 1) + '张图片');\r\n");
        code.append("            },\r\n");
        code.append("            fail: function(err) {\r\n");
        code.append("                //console.log(err.errMsg);\r\n");
        code.append("            }\r\n");
        code.append("        }\r\n");
        code.append("    		});\r\n");
        code.append("    }\r\n");
        code.append("    },\r\n");

        code.append("    components: {\r\n");
        code.append(componentStr);
        code.append("    }\r\n");
        code.append("}\r\n\r\n");
        code.append("</script>\r\n");

        code.append("<style>");
        code.append("\r\n\t.cu-modal {");
        code.append("\r\n\t\ttransform: scale(1);");
        code.append("\r\n\t}");
        code.append("\r\n");
        code.append("\r\n\t.cu-dialog {");
        code.append("\r\n\t\theight: 100%;");
        code.append("\r\n\t\tposition: relative;");
        code.append("\r\n\t}");
        code.append("\r\n");
        code.append("\r\n\t.btnbox {");
        code.append("\r\n\t\tposition: absolute;");
        code.append("\r\n\t\tbottom: 0;");
        code.append("\r\n\t\twidth: 100%;");
        code.append("\r\n\t\theight: 100upx;");
        code.append("\r\n\t\tline-height: 100upx;");
        code.append("\r\n\t\tfont-size: 32upx;");
        code.append("\r\n\t\tbackground-color: #fff;");
        code.append("\r\n\t\tbox-sizing: border-box;");
        code.append("\r\n\t}");
        code.append("\r\n");
        code.append("\r\n\t.contentBox {");
        code.append("\r\n\t\theight: calc(100% - 100upx);");
        code.append("\r\n\t\toverflow: auto;");
        code.append("\r\n\t\ttext-align: left;");
        code.append("\r\n\t\tpadding: 40upx 10upx;");
        code.append("\r\n\t\tbackground-color: #fff;");
        code.append("\r\n\t}");
        code.append("\r\n\t");
        code.append("\r\n\t.contentBox.sort {");
        code.append("\r\n\t\tpadding: 40upx;");
        code.append("\r\n\t}");
        code.append("\r\n");
        code.append("\r\n\t.show {");
        code.append("\r\n\t\tdisplay: block;");
        code.append("\r\n\t}");
        code.append("\r\n");
        code.append("\r\n\t.hide {");
        code.append("\r\n\t\tdisplay: none;");
        code.append("\r\n\t}");
        code.append("\r\n");
        code.append("\r\n\t.cuIcon-roundaddfill {");
        code.append("\r\n\t\tfont-size: 100upx;");
        code.append("\r\n\t\tright: 20upx;");
        code.append("\r\n\t\tbottom: 100upx;");
        code.append("\r\n\t\tposition: fixed;");
        code.append("\r\n\t}");
        code.append("\r\n");
        code.append("\r\n\t.cu-bar.fixed {");
        code.append("\r\n\t\tbox-shadow: none;");
        code.append("\r\n\t}");
        code.append("\r\n");
        code.append("\r\n\t.divider_bottom {");
        code.append("\r\n\t\tborder-bottom: 1px solid #f0f0f0;");
        code.append("\r\n\t}");
        code.append("\r\n");
        code.append("\r\n\t.s15 {");
        code.append("\r\n\t\tfont-size: 30upx;");
        code.append("\r\n\t}\r\n");
        code.append(".imgListPic{\r\n");
        code.append("    width: 200upx;\r\n");
        code.append("    height: 200upx;\r\n");
        code.append("    display: inline-block;\r\n");
        code.append("    margin-right: 20upx;\r\n");
        code.append("    vertical-align: middle;\r\n");
        code.append("}\r\n");
        code.append(".imgListPic uni-image{\r\n");
        code.append("    width: 100%;\r\n");
        code.append("    height: 100%;\r\n");
        code.append("    display: block;\r\n");
        code.append("}\r\n");
        code.append(".fileListbox{\r\n");
        code.append("   background-color: #e9fef8;\r\n");
        code.append("   border: 1px solid #b0f1e1;\r\n");
        code.append("   color: #00bb8e;\r\n");
        code.append("   border-radius: 5px;\r\n");
        code.append("   line-height: 14px;\r\n");
        code.append("   padding: 5px 10px;\r\n");
        code.append("   margin: 10px 0;\r\n");
        code.append("   font-size: 12px;\r\n");
        code.append("   word-break: break-all;\r\n");
        code.append("}\r\n");
        code.append(".fileListbox a{\r\n");
        code.append("    color: #00bb8e;\r\n");
        code.append("}\r\n");
        code.append(".con-label{\r\n");
        code.append("    display: inline-block;\r\n");
        code.append("    width: 120upx;\r\n");
        code.append("    vertical-align: middle;\r\n");
        code.append("}\r\n");
        code.append(".con-value{\r\n");
        code.append("    display: inline-block;\r\n");
        code.append("    width: calc(100% - 150upx);\r\n");
        code.append("    vertical-align: middle;\r\n");
        code.append("}\r\n");
        code.append("\r\n</style>");

        return code.toString();
    }

    public static String genFormViewCode(String moduleName, List<DbTableDto> dbTableModelList, List<Map<String, Object>>  formFieldList, BaseInfoDto baseModel, List<Map<String, Object>> eventData) {
        StringBuilder code = new StringBuilder();

        Set<String> importList = new LinkedHashSet<>(); //导入组件
        Set<String> componentList = new LinkedHashSet<>(); //注册
        code.append("<template>\r\n");
        code.append("   <view class=\"padding-bottom\">\r\n");
        code.append("       <Header class=\"header-box\" v-if=\"!formType\" :Top=\"StatusBar\">\r\n");
        code.append("           <block slot=\"content\">{{ titleName }}</block>\r\n");
        code.append("           <block slot=\"right\"><view style=\"width: 50px;\"></view></block>\r\n");
        code.append("       </Header>\r\n");
        code.append("       <view :style=\"{paddingTop:!formType?(StatusBar+50+'px'):0}\">\r\n");
        importList.add("import Header from \"@/components/workflow/Header.vue\";");
        componentList.add("Header");

        code.append("       <form :model=\"formData\" v-if=\"showForm\"> \r\n");

        List<String> configList = new ArrayList<>(); //各组件配置
        Map<String, StringBuilder> tableRuleMap = new HashMap<>(dbTableModelList.size()); //验证
        List<String> opinionFieldList = new ArrayList<>();//意见簿字段名
        String formDataStr = StringPool.EMPTY;//提交对象
//        String formatterStr = StringPool.EMPTY;//获取表单数据 格式化
//        String childTableRuleStr = StringPool.EMPTY;//子表单验证
//        String validateStr = StringPool.EMPTY;//提交验证
        String mainTableName = StringPool.EMPTY;
        for (DbTableDto table : dbTableModelList) {
            if (table.getParentName() == 1) {
                mainTableName = table.getName();
            }
        }

        boolean existSubTable = false;
        boolean existAsso = false;
        boolean existSubAsso = false;
        boolean existFinance = false;
        boolean existSubFinance = false;

        boolean isSingleTable = dbTableModelList.size() == 1;

        // 字段默认值
        Map<String, Map<String, Object>> defaultValueMap = new HashMap<>();

        for(Map<String, Object> field : formFieldList) {
            Map<String, Object> config = MapUtils.getMap(field, FormConstants.CONFIG);

            handleFormField(opinionFieldList, mainTableName, code, configList, importList, tableRuleMap, componentList, isSingleTable, defaultValueMap, field);

            String tag = MapUtils.getString(config, "tag");
            String avueType = MapUtils.getString(config, FormConstants.FORM_COMPONENT_TYPE);
            String componentName = MapUtils.getString(config, FormConstants.FORM_COMPONENT_NAME);
            if (StringUtil.equalsIgnoreCase(componentName, "avue-tabs")) {
                Map<String, List<Map<String, Object>>> childrenObj = MapUtils.getMap(config, "childrenObj");
                for (List<Map<String, Object>> tabFieldList : childrenObj.values()) {
                    for (Map<String, Object> tabField : tabFieldList) {
                        Map<String, Object> tabConfig = MapUtils.getMap(tabField, FormConstants.CONFIG);
                        String tabTag = MapUtils.getString(tabConfig, "tag");
                        String tabAvueType = MapUtils.getString(tabConfig, FormConstants.FORM_COMPONENT_TYPE);
                        String tabComponentName = MapUtils.getString(tabConfig, FormConstants.FORM_COMPONENT_NAME);
                        if (StringUtil.equalsIgnoreCase(tabAvueType, "asso-select") || StringUtil.equalsIgnoreCase(tabAvueType, "asso-popup")) {
                            existAsso = true;
                        } else if (StringUtil.equalsIgnoreCase(tabTag, "el-input") && StringUtil.equalsIgnoreCase(tabAvueType, "input")) {
                            existFinance = true;
                        } else if (StringUtil.equalsIgnoreCase(tabComponentName, "table")) {
                            existSubTable = true;
                            List<Map<String, Object>> children = (List<Map<String, Object>>) tabConfig.get(FormConstants.CHILDREN);
                            for (Map<String, Object> child : children) {
                                Map<String, Object> subConfig = MapUtils.getMap(child, FormConstants.CONFIG);
                                String subTag = MapUtils.getString(subConfig, "tag");
                                String subAvueType = MapUtils.getString(subConfig, FormConstants.FORM_COMPONENT_TYPE);
                                if (StringUtil.equalsIgnoreCase(subAvueType, "asso-select") || StringUtil.equalsIgnoreCase(subAvueType, "asso-popup")) {
                                    existSubAsso = true;
                                } else if (StringUtil.equalsIgnoreCase(subTag, "el-input") && StringUtil.equalsIgnoreCase(subAvueType, "input")) {
                                    existSubFinance = true;
                                }
                            }
                        }
                    }
                }
            }else {
                if (StringUtil.equalsIgnoreCase(avueType, "asso-select") || StringUtil.equalsIgnoreCase(avueType, "asso-popup")) {
                    existAsso = true;
                } else if (StringUtil.equalsIgnoreCase(tag, "el-input") && StringUtil.equalsIgnoreCase(avueType, "input")) {
                    existFinance = true;
                } else if (StringUtil.equalsIgnoreCase(componentName, "table")) {
                    existSubTable = true;
                    List<Map<String, Object>> children = (List<Map<String, Object>>) config.get(FormConstants.CHILDREN);
                    for (Map<String, Object> child : children) {
                        Map<String, Object> subConfig = MapUtils.getMap(child, FormConstants.CONFIG);
                        String subTag = MapUtils.getString(subConfig, "tag");
                        String subAvueType = MapUtils.getString(subConfig, FormConstants.FORM_COMPONENT_TYPE);
                        if (StringUtil.equalsIgnoreCase(subAvueType, "asso-select") || StringUtil.equalsIgnoreCase(subAvueType, "asso-popup")) {
                            existSubAsso = true;
                        } else if (StringUtil.equalsIgnoreCase(subTag, "el-input") && StringUtil.equalsIgnoreCase(subAvueType, "input")) {
                            existSubFinance = true;
                        }
                    }
                }
            }

        }

        //formdata 字符串构建
        // 如果是主表 默认使用entity  如果是附表 使用 entitylist

        //如果是多表 返回值会跟单表不一样
        // 单表 直接返回 单表的FormOutputDto
        //多表 返回值是 多个表的实体类
        for (DbTableDto table : dbTableModelList) {
            String tableName = table.getName();

            // 默认值
            StringBuilder defaultValueStr = new StringBuilder();
            Map<String, Object> map = defaultValueMap.get(tableName);
            for (Map.Entry<String, Object> entry : map.entrySet()) {
                Object value = entry.getValue();
                defaultValueStr.append(entry.getKey()).append(": ").append(StringUtil.isEmpty(value) ? "null" : "'" + value +"'").append(",");
            }

            if (table.getParentName() == 1) {
                mainTableName = tableName;


                if (dbTableModelList.size() > 1) {
                    formDataStr += tableName + " : {" + defaultValueStr + "},";
//                    formatterStr += "this.formData." + table.getName() + "Entity = res.data." + table.getName() + " \r\n";
                } else {
                    formDataStr += defaultValueStr;
//                    formatterStr += "this.formData." + table.getName() + "Entity = res.data \r\n";
                }
            } else {
                formDataStr += tableName + " : [],";
//                if (dbTableModelList.size() > 1) {
//                    formatterStr += "this.formData." + table.getName() + "EntityList = res.data." + table.getName() + ".length > 0 ? res.data." + table.getName() + " : [{}]\r\n";
//                }
            }
        }

        code.append("       </form> \r\n");
        code.append("       <button v-if=\"type == 'edit'\" class=\"bg-blue margin\" @click=\"submit\">提交</button> \r\n");
        code.append("       </view>\r\n");
        code.append("   </view>\r\n");
        code.append("</template>\r\n\r\n");

        code.append("<script>\r\n");

        code.append("   import workflowFormAuthorize from '@/components/workflow/mixins/workflowFormAuthorize.js'\r\n");
//        code.append("   import validate from '@/js_sdk/fshjie-formvalidate/ys-validate.js'\r\n");
        code.append("   import tool from '@/js_sdk/pocky-request/request/tools.js'\r\n");
        for (String importCode : importList) {
            code.append("   " + importCode + System.lineSeparator());
        }

        code.append("export default {\r\n");
        code.append("   mixins: [workflowFormAuthorize],\r\n");
        code.append("   props: {\r\n");
        code.append("       formType:{\r\n");
        code.append("           type: Boolean,\r\n");
        code.append("           default: () => {\r\n");
        code.append("               return false;\r\n");
        code.append("           }\r\n");
        code.append("       },\r\n");
        code.append("       formModels:{\r\n");
        code.append("           type: Object,\r\n");
        code.append("           default: () => {\r\n");
        code.append("               return {}\r\n");
        code.append("           }\r\n");
        code.append("       },\r\n");
        code.append("       disabled: {\r\n");
        code.append("           type: Boolean,\r\n");
        code.append("           default: () => {\r\n");
        code.append("               return false;\r\n");
        code.append("           }\r\n");
        code.append("       }\r\n");
        code.append("   },\r\n");
//        code.append("   computed: {\r\n");
//        code.append("       formData:{\r\n");
//        code.append("           get:function () {\r\n");
//        code.append("               return Object.keys(this.formModels).length!=0?this.formModels:tool.deepClone(this.formFields)\r\n");
//        code.append("           },\r\n");
//        code.append("           set:function(){\r\n");
//        code.append("               this.$emit(\"changeSystemValue\", this.formData);\r\n");
//        code.append("           }\r\n");
//        code.append("       }\r\n");
//        code.append("   },\r\n");
        code.append("   data() {\r\n");
        code.append("       return {\r\n");
        code.append("           StatusBar:this.StatusBar,\r\n");
        code.append("           formJson: {\r\n");
        for (String configCode : configList) {
            code.append("               " + configCode + System.lineSeparator());
        }
        code.append("           },\r\n");
        code.append("           formData: {\r\n");
        code.append("               " + formDataStr + "\r\n");
        code.append("           },\r\n");


        code.append("           rules : {\r\n");
        for (Map.Entry<String, StringBuilder> entry: tableRuleMap.entrySet()) {
            code.append("               \"" + entry.getKey() + "\":[" + entry.getValue().toString() + "],\r\n");
        }
        code.append("           },\r\n");
        code.append("           eventData:" + JSONObject.toJSONString(eventData) + ",\r\n");
        code.append("           verifyKey : [],\r\n");

        code.append("           type: '',\r\n");
        code.append("           keyValue: false,\r\n");
        code.append("           mainTableName: \"" + mainTableName + "\",\r\n");
        code.append("           titleName: '" + moduleName + "',\r\n");
        code.append("           interfaceUrl:'/" + baseModel.getName() + "/',\r\n");
        code.append("           showForm: false\r\n");
        code.append("       }\r\n");
        code.append("   },\r\n");
//
//        code.append("       if(options.keyValue){\r\n");
//        code.append("           this.showForm=false\r\n");
//        code.append("           uni.showLoading({\r\n");
//        code.append("               title:'加载中...',\r\n");
//        code.append("               mask:true\r\n");
//        code.append("           })\r\n");
//        code.append("           uni.setNavigationBarTitle({\r\n");
//        code.append("               title: (this.type=='edit'?'编辑':'查看') + this.titleName\r\n");
//        code.append("           });\r\n");
//        code.append("           this.keyValue = options.keyValue;\r\n");
//        code.append("           this.$http.request({\r\n");
//        code.append("               url: '/" + baseModel.getName().toLowerCase() + "/' + options.keyValue,\r\n");
//        code.append("               method: 'get'\r\n");
//        code.append("           }).then(res => {\r\n");
//        code.append("               this.showForm=true\r\n");
//        code.append("               this.formData = res.data\r\n");
//        code.append("               uni.hideLoading()\r\n");
//        // 意见簿字段回显处理
//        for (String opinionField : opinionFieldList) {
//            code.append("               if(!this.formData." + (isSingleTable ? StringPool.EMPTY : mainTableName + ".") + opinionField + ") this.formData." + (isSingleTable ? StringPool.EMPTY : mainTableName + ".") + opinionField + "='[]'");
//        }
//        code.append("           });\r\n");
//        code.append("       }\r\n");
//        code.append("   },\r\n");

//        code.append("   mounted() {\r\n");
//        code.append("       if (this.formModels.approvalFormData && Object.keys(this.formModels.approvalFormData).length != 0){\r\n");
//        code.append("           let source=this.formModels.approvalFormData;\r\n");
//        if (!isSingleTable) {
//            code.append("           for(let key in this.formData){\r\n");
//            code.append("               let obj=this.formData[key]\r\n");
//            code.append("               if(Array.isArray(obj)&&source[key]){\r\n");
//            code.append("                   this.formData[key]=source[key]\r\n");
//            code.append("               }else{\r\n");
//            code.append("                   for(let k in obj){\r\n");
//            code.append("                       if(source[key]&&source[key][k]){\r\n");
//            code.append("                           obj[k]=source[key][k]\r\n");
//            code.append("                       }\r\n");
//            code.append("                   }\r\n");
//            code.append("               }\r\n");
//            code.append("           }\r\n");
//        } else {
//            code.append("           for(let key in this.formData){\r\n");
//            code.append("               if(source[this.mainTableName]&&source[this.mainTableName][key]){\r\n");
//            code.append("                   this.formData[key]=source[this.mainTableName][key]\r\n");
//            code.append("               }\r\n");
//            code.append("           }\r\n");
//        }
//        code.append("       }\r\n");
//        code.append("       if(this.formModels.formJsonFields && Object.keys(this.formModels.formJsonFields).length!=0){\r\n");
//        code.append("           let source=this.formModels.formJsonFields;\r\n");
//        code.append("           for(let key in source){\r\n");
//        code.append("               let obj=source[key]\r\n");
//        code.append("               for(let k in obj){\r\n");
//        code.append("                   let chil=obj[k]\r\n");
//        code.append("                   if(this.formJson[key] && key.indexOf('Config')>=0){\r\n");
//        code.append("                       this.formJson[key][k]=obj[k]\r\n");
//        code.append("                   }\r\n");
//        code.append("                   if(k.indexOf('Config')>=0){\r\n");
//        code.append("                       for(let j in chil){\r\n");
//        code.append("                           if(this.formJson[key][k]){\r\n");
//        code.append("                               this.formJson[key][k][j]=chil[j]\r\n");
//        code.append("                           }\r\n");
//        code.append("                       }\r\n");
//        code.append("                   }\r\n");
//        code.append("               }\r\n");
//        code.append("           }\r\n");
//        code.append("       }\r\n");
//        code.append("       if(this.formModels.taskCommentList?.length>=0){\r\n");
//        code.append("           for(let el in this.formJson){\r\n");
//        code.append("               if (this.formJson[el].type == \"opinion\") {\r\n");
//        code.append("                   let taskKey = this.formModels.detail.F_FormId + \"-\" + el.formId;\r\n");
//        code.append("                   let taskValue = taskCommentList.has(taskKey)\r\n");
//        code.append("                           ? taskCommentList.get(taskKey)\r\n");
//        code.append("                           : [];\r\n");
//        code.append("                   if(Object.keys(this.formData).length>0){\r\n");
//        code.append("                       let res=new Map(Object.entries(this.formData))\r\n");
//        code.append("                       if(res.has(this.mainTableName)){\r\n");
//        code.append("                           this.formData[this.mainTableName][this.formJson[el].fieldsId]=JSON.stringify(taskValue)\r\n");
//        code.append("                       }else{\r\n");
//        code.append("                           this.formData[this.formJson[el].fieldsId]=JSON.stringify(taskValue)\r\n");
//        code.append("                       }\r\n");
//        code.append("                   }\r\n");
//        code.append("               }\r\n");
//        code.append("           }\r\n");
//        code.append("       }\r\n");
//        code.append("       this.$emit(\"defaultSystemValue\", {formData:this.formData,rules:this.rules,verifyKey:this.verifyKey,mainTable:this.mainTableName,infoIndex:this.formModels.infoIndex});\r\n");
//        code.append("       if(!this.keyValue) this.showForm=true\r\n");
//        code.append("   },\r\n");

        code.append("   methods: {\r\n");
        // 表格组件
        if (existSubTable) {
            code.append("        deleteTable(table,childIndex) {\r\n");
            code.append("            this.formData[table].splice(childIndex, 1);\r\n");
            code.append("        },\r\n");
            code.append("        addTable(table) {\r\n");
            code.append("            let reusltItem = {};\r\n");
            code.append("            for(let key in this.formJson[table]){\r\n");
            code.append("               let k=key.split('Config')[0]\r\n");
            code.append("               if(this.hasTableField(table,k)){\r\n");
            code.append("                   reusltItem[k]=this.formJson[table][key].value\r\n");
            code.append("               }\r\n");
            code.append("               reusltItem[k]=this.formJson[table][key].value\r\n");
            code.append("            };\r\n");
            code.append("            this.formData[table].push(reusltItem);\r\n");
            code.append("        },\r\n");
        }
        // 联想组件
        if (existAsso) {
//            code.append("        changeAssociative(data){\r\n");
//            code.append("            if(data.conf.type=='assoPopup'||data.conf.type=='assoSelect'){\r\n");
//            code.append("                let fields=JSON.parse(data.conf.autoBindFields)\r\n");
//            code.append("                fields.forEach(it=>{\r\n");
//            code.append("                if(it.field){\r\n");
//            if (isSingleTable) {
//                code.append("                       this.formData[it.field]=data.data[it.bindField]\r\n");
//            } else {
//                code.append("                       this.formData[data.conf.table][it.field]=data.data[it.bindField]\r\n");
//            }
//            code.append("                }\r\n");
//            code.append("          })\r\n");
//            code.append("            }\r\n");
//            code.append("        },\r\n");

        }
        if (existSubAsso) {
            //只有子表单中有联想弹层或者联想下拉才加这个方法
            code.append("        changeTableAssociative(data){\r\n");
            code.append("            if(data.conf.type=='assoPopup'||data.conf.type=='assoSelect'){\r\n");
            code.append("                let fields=JSON.parse(data.conf.autoBindFields)\r\n");
            code.append("                fields.forEach(it=>{\r\n");
            code.append("                   if(it.field){\r\n");
            code.append("                       this.formData[data.conf.table][data.childIndex][it.field]=data.data[it.bindField]\r\n");
            code.append("                   }\r\n");
            code.append("               })\r\n");
            code.append("            }\r\n");
            code.append("        },\r\n");
        }

        if (existFinance || existSubFinance) {
            // 只要有财务组件才写（无论主子表）
//            code.append("        findObjById(json,id){\r\n");
//            code.append("            for(let key in json){\r\n");
//            code.append("                for(let j in json[key]){\r\n");
//            code.append("                    if(j=='formId'&&json[key][j]==id){\r\n");
//            code.append("                        return json[key]\r\n");
//            code.append("                    }\r\n");
//            code.append("                }\r\n");
//            code.append("            }\r\n");
//            code.append("            return null;\r\n");
//            code.append("        },\r\n");
        }

        if (existFinance) {
//            code.append("        changePopupList(data){\r\n");
//            code.append("            this.computePublicFun(data.conf)\r\n");
//            code.append("        },\r\n");
//            code.append("        blurChange(data){\r\n");
//            code.append("            console.log(this.formData);\r\n");
//            code.append("            if(data.value){\r\n");
//            code.append("                if(!(/^\\d+(.\\d{0,2})?$/).test(data.value)){\r\n");
//            if (isSingleTable) {
//                code.append("                       this.formData[data.conf.field]=parseFloat(data.value).toFixed(2)\r\n");
//            } else {
//                code.append("                       this.formData[data.conf.table][data.conf.field]=parseFloat(data.value).toFixed(2)\r\n");
//            }
//            code.append("                }\r\n");
//            code.append("            }\r\n");
//            code.append("        },\r\n");

//            code.append("        computePublicFun(conf){\r\n");
//            code.append("            if(conf.relative?.length>0){\r\n");
//            code.append("               conf.relative.forEach(it=>{\r\n");
//            code.append("                        let obj=this.findObjById(this.formJson,it)\r\n");
//            code.append("                if(obj){\r\n");
//            code.append("                    let computation=obj.computation;\r\n");
//            if (isSingleTable) {
//                code.append("                       this.formData[obj.field]=0;\r\n");
//            } else {
//                code.append("                       this.formData[obj.table][obj.field]=0;\r\n");
//            }
//            code.append("                    let computeStr='';\r\n");
//            code.append("                    computation.forEach(i=>{\r\n");
//            code.append("                    if(i.formId>0){\r\n");
//            code.append("                        let cur=this.findObjById(this.formJson,i.formId)\r\n");
//            code.append("                        if(cur){\r\n");
//            if (isSingleTable) {
//                code.append("                               computeStr+=this.formData[cur.field]||0\r\n");
//            } else {
//                code.append("                               computeStr+=this.formData[cur.table][cur.field]||0\r\n");
//            }
//            code.append("                        }\r\n");
//            code.append("                    }else{\r\n");
//            code.append("                        if (i.type == \"taxRate\") {\r\n");
//            code.append("                            //税率\r\n");
//            code.append("                            if (obj.taxRate >= 0) {\r\n");
//            code.append("                                computeStr += obj.taxRate * 0.01;\r\n");
//            code.append("                            }\r\n");
//            code.append("                        }else{\r\n");
//            code.append("                            computeStr+=i.name\r\n");
//            code.append("                        }\r\n");
//            code.append("                   }\r\n");
//            code.append("        		})\r\n");
//            code.append("                    let res=eval(computeStr)\r\n");
//            code.append("                    if(!(/^\\d+(.\\d{0,2})?$/).test(res)){\r\n");
//            code.append("                        res=parseFloat(res).toFixed(2)\r\n");
//            code.append("                    }\r\n");
//            if (isSingleTable) {
//                code.append("                       this.formData[obj.field]=res;\r\n");
//            } else {
//                code.append("                       this.formData[obj.table][obj.field]=res;\r\n");
//            }
//            code.append("                    //console.log(computeStr,'computeStr+=')\r\n");
//            code.append("                    this.computePublicFun(obj)\r\n");
//            code.append("                }\r\n");
//            code.append("        })\r\n");
//            code.append("            }\r\n");
//            code.append("        },\r\n");

        }
        if (existSubFinance) {
            //只有子表单中有财务组件才加这个方法
            code.append("        blurTableChange(data){\r\n");
            code.append("            if(data.value){\r\n");
            code.append("                if(!(/^\\d+(.\\d{0,2})?$/).test(data.value)){\r\n");
            code.append("                    this.formData[data.conf.table][data.childIndex][data.conf.field]=parseFloat(data.value).toFixed(2)\r\n");
            code.append("                }\r\n");
            code.append("            }\r\n");
            code.append("        },\r\n");
            //只有子表单中有财务组件才加这个方法
            code.append("        changeTablePopupList(data){\r\n");
            code.append("            this.computeTablePublicFun(data.conf,data.childIndex)\r\n");
            code.append("        },\r\n");
            code.append("        computeTablePublicFun(conf,index){\r\n");
            code.append("            if(conf.relative?.length>0){\r\n");
            code.append("                conf.relative.forEach(it=>{\r\n");
            code.append("                        let obj=this.findObjById(this.formJson[conf.table],it)\r\n");
            code.append("                if(obj){\r\n");
            code.append("                    let computation=obj.computation;\r\n");
            code.append("                    this.formData[obj.table][index][obj.field]=0;\r\n");
            code.append("                    let computeStr='';\r\n");
            code.append("                    computation.forEach(i=>{\r\n");
            code.append("                    if(i.formId>0){\r\n");
            code.append("                        let cur=this.findObjById(this.formJson[obj.table],i.formId)\r\n");
            code.append("                        if(cur){\r\n");
            code.append("                            computeStr+=this.formData[cur.table][index][cur.field]||0\r\n");
            code.append("                        }\r\n");
            code.append("                    }else{\r\n");
            code.append("                        if (i.type == \"taxRate\") {\r\n");
            code.append("                            //税率\r\n");
            code.append("                            if (obj.taxRate >= 0) {\r\n");
            code.append("                                computeStr += obj.taxRate * 0.01;\r\n");
            code.append("                            }\r\n");
            code.append("                        }else{\r\n");
            code.append("                            computeStr+=i.name\r\n");
            code.append("                        }\r\n");
            code.append("                    }\r\n");
            code.append("        	})\r\n");
            code.append("                    let res=eval(computeStr)\r\n");
            code.append("                    if(!(/^\\d+(.\\d{0,2})?$/).test(res)){\r\n");
            code.append("                        res=parseFloat(res).toFixed(2)\r\n");
            code.append("                    }\r\n");
            code.append("                    this.formData[obj.table][index][obj.field]=res;\r\n");
            code.append("                    this.computeTablePublicFun(obj,index)\r\n");
            code.append("                }\r\n");
            code.append("          })\r\n");
            code.append("            }\r\n");
            code.append("        },\r\n");
        }


//        code.append("        submit() {\r\n");
//
//        code.append("           let flag=true;\r\n");
//        code.append("           let messge='';\r\n");
//        code.append("           for(let key in this.formData){\r\n");
////        code.append("               for (let [k, v] of Object.entries(this.formData[key])) {\r\n");
//        if (isSingleTable) {
//            code.append("                   if (this.rules[key]&&this.verifyKey.includes(key)) {\r\n");
//            code.append("                       let val = validate.validate(\r\n");
//            code.append("                               this.formData,\r\n");
//            code.append("                               this.rules[key]\r\n");
//            code.append("                       );\r\n");
//            code.append("                       if (!val.isOk) {\r\n");
//            code.append("                           messge = \"表单：\" + val.errmsg;\r\n");
//            code.append("                           flag=false;\r\n");
//            code.append("                           uni.showToast({\r\n");
//            code.append("                                  title: messge,\r\n");
//            code.append("                                   icon: \"none\",\r\n");
//            code.append("                                   position: \"top\",mask:true\r\n");
//            code.append("                                   });\r\n");
//            code.append("                           return;\r\n");
//            code.append("                       }\r\n");
//            code.append("                   }\r\n");
//        } else {
//            code.append("                   if (Array.isArray(this.formData[key])) {\r\n");
//            code.append("                       //子表单\r\n");
//            code.append("                       for(let index=0;index<this.formData[key].length;index++){\r\n");
//            code.append("                           let it=this.formData[key][index]\r\n");
//            code.append("                           for(let j in it){\r\n");
//            code.append("                               //过滤掉当前不参与匹配的校验规则，否则一直空提示\r\n");
//            code.append("                               let tempRule=this.rules[key].filter(o=>{return o.name==j})||[]\r\n");
//            code.append("                               if (this.verifyKey.includes(j)&&tempRule) {\r\n");
//            code.append("                                  let val = validate.validate(\r\n");
//            code.append("                                           it,\r\n");
//            code.append("                                           tempRule\r\n");
//            code.append("                                   );\r\n");
//            code.append("                                   if (!val.isOk) {\r\n");
//            code.append("                                       messge = \"子表单：\" + val.errmsg;\r\n");
//            code.append("                                       flag=false;\r\n");
//            code.append("                                       uni.showToast({\r\n");
//            code.append("                                               title: messge,\r\n");
//            code.append("                                               icon: \"none\",\r\n");
//            code.append("                                               position: \"top\",\r\n");
//            code.append("                                               });\r\n");
//            code.append("                                       return;\r\n");
//            code.append("                                   }else{\r\n");
//            code.append("                                       //flag=true;\r\n");
//            code.append("                                   }\r\n");
//            code.append("                               }\r\n");
//            code.append("                           }\r\n");
//            code.append("                       }\r\n");
//            code.append("                   } else {\r\n");
//            code.append("                       for(let i in this.formData[key]){\r\n");
//            code.append("                           if (this.rules[key]&&this.verifyKey.includes(i)) {\r\n");
//            code.append("                               let val = validate.validate(\r\n");
//            code.append("                                       this.formData[key],\r\n");
//            code.append("                                       this.rules[key]\r\n");
//            code.append("                               );\r\n");
//            code.append("                               if (!val.isOk) {\r\n");
//            code.append("                                   messge = \"表单：\" + val.errmsg;\r\n");
//            code.append("                                   flag=false;\r\n");
//            code.append("                                   uni.showToast({\r\n");
//            code.append("                                           title: messge,\r\n");
//            code.append("                                           icon: \"none\",\r\n");
//            code.append("                                           position: \"top\",\r\n");
//            code.append("                                           });\r\n");
//            code.append("                                   return;\r\n");
//            code.append("                               }\r\n");
//            code.append("                           }\r\n");
//            code.append("                       }\r\n");
//            code.append("                   }\r\n");
////        code.append("           }\r\n");
//        }
//        code.append("           } \r\n");
//
//        code.append("           if (!flag) {\r\n");
//        code.append("               return;\r\n");
//        code.append("           }\r\n");
//        if (!isSingleTable) {
//            code.append("           for(let key in this.formData){\r\n");
//            code.append("              if(key==this.mainTableName && !this.formData[key+'Entity']){\r\n");
//            code.append("                   this.formData[key+'Entity']=this.formData[key]\r\n");
//            code.append("               }else if(key!=this.mainTableName && !this.formData[key+'EntityList']){\r\n");
//            code.append("                   this.formData[key+'EntityList']=this.formData[key]\r\n");
//            code.append("               }\r\n");
//            code.append("               delete this.formData[key]\r\n");
//            code.append("           }\r\n");
//        } else {
//
//            code.append("            let tempData={}\r\n");
//            code.append("            tempData[this.mainTableName+'Entity']=this.formData\r\n");
//        }
//        String submitData = isSingleTable ? "tempData" : "this.formData";
//        String tempData = isSingleTable ? "tempData" : "";
//        code.append("            uni.showLoading({title: '提交中'}); \r\n");
//        code.append("            if (this.keyValue) { \r\n");
//        code.append("                this.$http.request({ \r\n");
//        code.append("                    url: '/" + baseModel.getName().toLowerCase() + "/' + this.keyValue, \r\n");
//        code.append("                    method: 'put', \r\n");
//        code.append("                    data: " + submitData + " \r\n");
//        code.append("                }).then(res=>{ \r\n");
//        code.append("                    if(res.code){\r\n");
//        code.append("                       uni.showToast({\r\n");
//        code.append("                           title: '提交失败'\r\n");
//        code.append("                        });\r\n");
//        code.append("                    }else{\r\n");
//        code.append("                       this.goBack(" + tempData + ")\r\n");
//        code.append("                    }");
//        code.append("                });\r\n");
//        code.append("            } \r\n");
//        code.append("            else { \r\n");
//        code.append("                this.$http.request({ \r\n");
//        code.append("                    url: '/" + baseModel.getName().toLowerCase() + "', \r\n");
//        code.append("                    method: 'post', \r\n");
//        code.append("                    data: " + submitData + " \r\n");
//        code.append("                }).then(res=>{ \r\n");
//        code.append("                    if(res.code){\r\n");
//        code.append("                       uni.showToast({\r\n");
//        code.append("                           title: '提交失败'\r\n");
//        code.append("                        });\r\n");
//        code.append("                    }else{\r\n");
//        code.append("                       this.goBack(" + tempData + ")\r\n");
//        code.append("                    }");
//        code.append("                }); \r\n");
//        code.append("            } \r\n");
//
//        code.append("        },\r\n");
//        code.append("        goBack(" + tempData + "){\r\n");
//        code.append("            uni.showToast({\r\n");
//        code.append("                    title: '提交成功'\r\n");
//        code.append("        		});\r\n");
//        code.append("           uni.navigateBack({\r\n");
//        code.append("                    success: () => {\r\n");
//        code.append("                let pages = getCurrentPages(); //跳转页面成功之后\r\n");
//        code.append("                let prevPage = pages[pages.length - 2];\r\n");
//        code.append("                if (!prevPage) return;\r\n");
//        code.append("               prevPage.navBack(" + submitData + "." + mainTableName + "Entity);\r\n");
//        code.append("            }\r\n");
//        code.append("        		});\r\n");
//        code.append("        }\r\n");
        code.append("    },\r\n");
        code.append("   components: {\r\n");
        for (String componentCode : componentList) {
            code.append("       " + componentCode + StringPool.COMMA + System.lineSeparator());
        }
        code.append("   },\r\n");




        code.append("};\r\n\r\n");
        code.append("</script>\r\n");

        code.append("<style scoped>");
        code.append("\r\n\t.title {");
        code.append("\r\n\t\tpadding: 10px;");
        code.append("\r\n\t\tfont-weight: bold;");
        code.append("\r\n\t}");
        code.append("\r\n");
        code.append("\r\n\t.formBox {");
        code.append("\r\n\t\tpadding: 10px;");
        code.append("\r\n\t\tbackground: rgba(0, 0, 0, .1);");
        code.append("\r\n\t\tborder-radius: 10px;");
        code.append("\r\n\t}");
        code.append("\r\n</style>");

        return code.toString();
    }

    private static void handleFormField(List<String> opinionFieldList, String mainTableName, StringBuilder code, List<String> configList, Set<String> importList, Map<String, StringBuilder> tableRuleMap, Set<String> componentList, boolean isSingleTable, Map<String, Map<String, Object>> defaultValueMap, Map<String, Object> field) {
        handleFormField(opinionFieldList, mainTableName, code, configList, importList, tableRuleMap, componentList, isSingleTable, defaultValueMap, field, StringPool.EMPTY, false);
    }

    private static void handleFormField(List<String> opinionFieldList, String mainTableName, StringBuilder code, List<String> configList, Set<String> importList, Map<String, StringBuilder> tableRuleMap, Set<String> componentList, boolean isSingleTable, Map<String, Map<String, Object>> defaultValueMap, Map<String, Object> field, String intentSpace, boolean isSubTable) {
        Map<String, Object> config = MapUtils.getMap(field, FormConstants.CONFIG);
        String tableName = MapUtils.getString(config, FormConstants.BIND_TABLE);
        String fieldName = MapUtils.getString(config, FormConstants.BIND_TABLE_FIELD);
        String fieldLabel = MapUtils.getString(config, "label");

        // 意见簿字段
        if (StringUtil.equalsIgnoreCase(MapUtils.getString(field, "__type__"), "opinion")) {
            opinionFieldList.add(MapUtils.getString(field, "__vModel__"));
        }

        // 默认值
        if (!StringUtil.isEmpty(fieldName)) {
            Map<String, Object> map = defaultValueMap.get(tableName);
            if (map == null) {
                map = new HashMap<>();
                defaultValueMap.put(tableName, map);
            }
            Object defaultValue = MapUtils.getObject(config, "defaultValue");
            if (defaultValue instanceof Collection) {
                defaultValue = handleListDefaultValue(defaultValue);
            } else if (StringUtil.equalsIgnoreCase(MapUtils.getString(config, "avueType"), "information-body")) {
                defaultValue = null;
            }
            map.put(fieldName, defaultValue);
        } else if (StringUtil.equalsIgnoreCase(MapUtils.getString(field, "__type__"), "opinion")) {
            // 意见簿默认值
            Map<String, Object> map = defaultValueMap.get(mainTableName);
            if (map == null) {
                map = new HashMap<>();
                defaultValueMap.put(mainTableName, map);
            }
            map.put(MapUtils.getString(field, "__vModel__"), "[]");
        }

        //如果验证信息不为空
        boolean required = MapUtils.getBoolean(config, "required", false);
        boolean isInfo = StringUtil.equalsIgnoreCase(MapUtils.getString(config, "avueType"), "information-body");
        if (required && !isInfo) {
            String ruleKeyName = isSingleTable ? fieldName : tableName;
            StringBuilder ruleStr = tableRuleMap.get(ruleKeyName);
            if (ruleStr == null) {
                ruleStr = new StringBuilder();
                tableRuleMap.put(ruleKeyName, ruleStr);
            }
            ruleStr.append("{name : '" + fieldName + "',type:'NotNull',title:'" + fieldLabel + "'},");
        }

        String componentName = MapUtils.getString(config, "componentName");
        if (StringUtils.equalsIgnoreCase(componentName, "avue-tabs")) {
            String tabFormId = MapUtils.getString(config, "formId");
            code.append(intentSpace + "           <view class=\"item-box margin-bottom-sm\">\r\n");
            code.append(intentSpace + "               <!--tabs选项卡-->\r\n");
            code.append(intentSpace + "               <scroll-view scroll-x=\"true\" class=\"padding-top-sm\" scroll-left=\"120\" style=\"height: 50px;white-space: nowrap;\">\r\n");
            code.append(intentSpace + "                   <view\r\n");
            code.append(intentSpace + "                       v-for=\"(item, index) in formJson.tab" + tabFormId + ".tabList\"\r\n");
            code.append(intentSpace + "                       :key=\"index\"\r\n");
            code.append(intentSpace + "                       @click=\"formJson.tab" + tabFormId + ".tabIndex = index\"\r\n");
            code.append(intentSpace + "                       :class=\"formJson.tab" + tabFormId + ".tabIndex == index ? 'tab-item tab-checked-item' : 'tab-item'\"\r\n");
            code.append(intentSpace + "                       ><text>{{ item.name }}</text></view>\r\n");
            code.append(intentSpace + "               </scroll-view>\r\n");
            code.append(intentSpace + "               <view>\r\n");
            Map<String, List<Map<String, Object>>> childrenObj = MapUtils.getMap(config, "childrenObj");
            Map<String, Object> option = MapUtils.getMap(config, "option");
            List<Map<String, Object>> tabColumnList = (List<Map<String, Object>>) option.get("column");
            int tabIndex = 0;
            // 选项卡配置
            String columnConfigStr = StringPool.EMPTY;
            // 处理选项卡字段
            String tabIntentSpace = intentSpace + "          "; // 代码缩进
            for (Map<String, Object> column : tabColumnList) {
                List<Map<String, Object>> child = childrenObj.get(MapUtils.getString(column, "prop"));
                if (CollectionUtil.isEmpty(child)) {
                    continue;
                }
                code.append(intentSpace + "                   <view v-show=\"formJson.tab" + tabFormId + ".tabIndex == " + tabIndex + "\">\r\n");
                for (Map<String, Object> tabField : child) {
                    handleFormField(opinionFieldList, mainTableName, code, configList,importList, tableRuleMap, componentList, isSingleTable, defaultValueMap, tabField, tabIntentSpace, false);
                }
                code.append(intentSpace + "                   </view>\r\n");
                tabIndex++;
                columnConfigStr += "{name:'" + column.get("label") + "'},";
            }
            code.append(intentSpace + "               </view>\r\n");
            code.append(intentSpace + "           </view>\r\n");
            configList.add("tab" + tabFormId + " : { tabList:[" + columnConfigStr + "],tabIndex:0,formId:" + tabFormId + "},");
        } else if (StringUtils.equalsIgnoreCase(componentName, "table")) {
            //便利表格所有列配置
            code.append(intentSpace + "           <view class=\"item-box margin-bottom\"  v-if=\"hasFormPermission('" + tableName + "')\">\r\n");
            code.append(intentSpace + "               <view  class=\"title padding-left padding-top-sm title-color bg-white\">" + MapUtils.getString(config, "componentTitle") + "</view>\r\n");
            code.append(intentSpace + "               <view v-for=\"(item, childIndex) in formData." + tableName + "\" :key=\"childIndex\">\r\n");
            code.append(intentSpace + "                   <view class=\"bg-white border-bottom padding-bottom-sm padding-top-sm\" v-if=\"!(formType?disabled:(type=='look'?true:false))\">\r\n");
            code.append(intentSpace + "                       <view class=\"flex justify-between padding-left-sm padding-right-sm remove-box\">\r\n");
            code.append(intentSpace + "                           <view>编辑（第{{childIndex + 1}}行）</view>\r\n");
            code.append(intentSpace + "                           <view @tap=\"deleteTable('" + tableName + "',childIndex)\">删除</view>\r\n");
            code.append(intentSpace + "                       </view>\r\n");
            code.append(intentSpace + "                   </view>\r\n");

//                String childrule = StringPool.EMPTY;
            // 子表单字段处理
            List<String> subFieldConfig = new ArrayList<>();
            String tableIntentSpace = intentSpace + "      ";//缩进长度
            List<Map<String, Object>> children = (List<Map<String, Object>>) config.get(FormConstants.CHILDREN);
            String subTableName = MapUtils.getString(config, FormConstants.BIND_TABLE);
            for (Map<String, Object> subField : children) {
                Map<String, Object> subConfig = MapUtils.getMap(subField, FormConstants.CONFIG);
                String subFieldName = MapUtils.getString(subConfig, FormConstants.BIND_TABLE_FIELD);

                // 默认值
                Object subDefaultValue = MapUtils.getMap(subConfig, "defaultValue");
                if (!StringUtil.isEmpty(subFieldName)) {
                    Map<String, Object> map = defaultValueMap.get(tableName);
                    if (map == null) {
                        map = new HashMap<>();
                        defaultValueMap.put(tableName, map);
                    }
                    map.put(subFieldName, subDefaultValue);
                }

                handleFormField(opinionFieldList, mainTableName, code, subFieldConfig, importList, tableRuleMap, componentList, isSingleTable, defaultValueMap, subField, tableIntentSpace, true);

            }

            // 处理子表单配置
            String subFieldConfigCodeStr = StringPool.EMPTY;
            for (String subConfigCode : subFieldConfig) {
                subFieldConfigCodeStr += subConfigCode;
            }
            String dataType = MapUtils.getString(config, "dataType");
            String preLoadConfig = StringPool.EMPTY;
            if (!StringUtils.isEmpty(dataType)) {
                preLoadConfig += "dataType:\"" + dataType + "\", ";
                if (StringUtils.equalsIgnoreCase(dataType, "dataSource")) {
                    preLoadConfig += "dataSource:\"" + MapUtils.getString(config, "dataSource") + "\",";
                } else {
                    preLoadConfig += "\"dataItem\":\"" + MapUtils.getString(config, "dataItem") + "\",";
                }
            }
            configList.add(tableName + ":{" + preLoadConfig + subFieldConfigCodeStr + "},");

//                childTableRuleStr += subTableName + "rules : [" + childrule + "],";


            code.append(intentSpace + "               </view>\r\n");
            code.append(intentSpace + "               <view v-if=\"!(formType?disabled:(type=='look'?true:false))\" class=\"text-center add-form-box\">\r\n");
            code.append(intentSpace + "                 <view @tap=\"addTable('" + subTableName + "')\">+ 新增一行</view>\r\n");
            code.append(intentSpace + "               </view>\r\n");
            code.append(intentSpace + "           </view>\r\n");
        } else {
            buildFieldComponent(mainTableName, field, code, importList, componentList, configList, intentSpace, isSubTable, isSingleTable);
        }
    }

    private static void buildFieldComponent(String mainTableName, Map<String, Object> field,StringBuilder code, Set<String> importList, Set<String> componentList, List<String> configList, String intentSpace, boolean isSubTable, boolean isSingleTable) {
        Map<String, Object> config = MapUtils.getMap(field, FormConstants.CONFIG);
        String avueType = MapUtils.getString(config, FormConstants.FORM_COMPONENT_TYPE);
        String fieldName = MapUtils.getString(config, FormConstants.BIND_TABLE_FIELD);
        String fieldLabel = MapUtils.getString(config, "label");
        String tableName = MapUtils.getString(config, FormConstants.BIND_TABLE);
        Integer formId = MapUtils.getInteger(config, "formId");
        Object defaultValue = MapUtils.getObject(config, "defaultValue", StringPool.EMPTY);
        Boolean required = MapUtils.getBoolean(config, "required", false);
        // 子表特殊代码
        String tableIndexCode = isSubTable ? "[childIndex]" : StringPool.EMPTY;
        String subTableNameCode = isSubTable ? tableName + "." : StringPool.EMPTY;
        String tag = MapUtils.getString(config, "tag");
        // 数据源数据字典处理
        String dataType = MapUtils.getString(config, "dataType");
        String dataSource = getDataSourceByType(dataType);
        String dataItem = getDataItem(config, dataSource);
        // API数据来源附加代码
        String apiCode = StringPool.EMPTY;
        if (StringUtil.equalsIgnoreCase(dataType, "dataApi")) {
            apiCode = ",apiQuerys:{},apiConfig:" + JSONObject.toJSONString(config.get("apiConfig"));
        }
        // 表单触发事件
        String triggerCompCode = StringPool.EMPTY;
        String triggerConfigCode = StringPool.EMPTY;
        Map<String, List<Object>> triggerEventData = MapUtils.getMap(config, "triggerEventData");
        if (triggerEventData != null) {
            boolean existEvent = triggerEventData.values().stream().anyMatch(value -> CollectionUtil.isNotEmpty(value));
            if (existEvent) {
                triggerConfigCode = ",triggerEvents: " + JSONObject.toJSONString(config.get("triggerEvents")) + ", triggerEventData: " + JSONObject.toJSONString(triggerEventData);
                triggerCompCode = " @changeBrother=\"changeBrother\"";
            }
        }

        // 组件属性编码
        String attrCode = StringPool.EMPTY;
        attrCode += !field.containsKey("readonly") ? StringPool.EMPTY : ",readonly: " + MapUtils.getBoolean(field, "readonly", false);
        attrCode += !field.containsKey("disabled") ? StringPool.EMPTY : ",disabled: " + MapUtils.getBoolean(field, "disabled", false);
        attrCode += !config.containsKey("required") ? StringPool.EMPTY : ",verify: " + required;
        attrCode += !field.containsKey("clearable") ? StringPool.EMPTY : ",clearable: " + MapUtils.getBoolean(field, "clearable", true);

        String formDataTableName = isSingleTable ? StringPool.EMPTY : "." + tableName;

        // 子表预加载
        String preLoadCode = isSubTable ? "\"prestrainField\":\"" + MapUtils.getString(config, "prestrainField", StringPool.EMPTY) + "\"," : StringPool.EMPTY;

        //字段权限代码
        String authCode = isSubTable ? " v-if=\"hasTableField('" + tableName + "', '" + fieldName + "')\" " : " v-if=\"hasFormPermission('" + fieldName + "')\" ";

        switch (tag) {
            //标题
            case "h2":
                code.append(intentSpace + "           <view class=\"padding-sm bg-white\" :style=\"{color:formJson.title" + formId + "Config.color,");
                code.append(intentSpace + "           fontSize:formJson.title" + formId + "Config.fontSize,");
                code.append(intentSpace + "           textAlign:formJson.title" + formId + "Config.align}\">{{ formJson.title" + formId + "Config.title }}</view>");
                configList.add("title" + formId + "Config : { 'title':'" + fieldLabel + "',color:'" + defaultValue + "',fontSize:'" + MapUtils.getString(config, "fontSize") + "',align:'" + MapUtils.getString(config, "titlePosition") + "', formId:" + formId + attrCode + "},");
                importList.add("import xjrInput from \"@/components/form/Input/Input.vue\"");
                componentList.add("xjrInput");
                break;
            case "el-input":
                //单行文本
                if (StringUtils.equalsIgnoreCase(avueType, "input-tip")) {
                    code.append(intentSpace + "           <xjr-input v-model=\"formData" + formDataTableName + tableIndexCode + "." + fieldName + "\"" + authCode + " :inputConfig=\"formJson." + subTableNameCode + fieldName  + "Config\"" + triggerCompCode + " :disabled=\"formType?disabled:(type=='look'?true:false)\"></xjr-input> \r\n");
                    configList.add(fieldName + "Config : { 'title':'" + fieldLabel + "',placeholder : '请填写" + fieldLabel + "', " +preLoadCode+ "maxlength:" + MapUtils.getInteger(field, "maxlength") + ",value:\"" + defaultValue + "\", formId:" + formId + attrCode + triggerConfigCode + "},");
                    importList.add("import xjrInput from \"@/components/form/Input/Input.vue\"");
                    componentList.add("xjrInput");
                //多行文本
                } else if (StringUtils.equalsIgnoreCase(avueType, "textarea")) {
                    code.append(intentSpace + "           <xjr-text-area v-model=\"formData" + formDataTableName + tableIndexCode + "." + fieldName + "\"" + authCode + " :textAreaConfig=\"formJson." + subTableNameCode + fieldName + "Config\" " + triggerCompCode + " :disabled=\"formType?disabled:(type=='look'?true:false)\"></xjr-text-area> \r\n");
                    Map<String, Object> autosize = MapUtils.getMap(field, "autosize");
                    configList.add(fieldName + "Config : { 'title':'" + fieldLabel + "',placeholder : '请填写" + fieldLabel + "', " +preLoadCode+ "maxlength:" + MapUtils.getInteger(field, "maxlength") + ",minHeight:" + MapUtils.getInteger(autosize, "minRows")*20 + ",maxHeight:" + MapUtils.getInteger(autosize, "maxRows")*20 + ",value:\"" + defaultValue + "\", formId:" + formId + attrCode + triggerConfigCode + "},");
                    importList.add("import xjrTextArea from \"@/components/form/TextArea/TextArea.vue\"");
                    componentList.add("xjrTextArea");
                //财务组件
                } else if (StringUtils.equalsIgnoreCase(avueType, "input")) {
                    String indexCode = isSubTable ? " :childIndex=\"childIndex\"" : StringPool.EMPTY;
                    String popupMethodCode = isSubTable ? "changeTablePopupList" : "changePopupList";
                    String blurMethodCode = isSubTable ? "blurTableChange" : "blurChange";
                    code.append(intentSpace + "           <xjr-input-number v-model=\"formData" + formDataTableName + tableIndexCode + "." + fieldName + "\"" + authCode + " :config=\"formJson." + subTableNameCode + fieldName + "Config\"" + indexCode + " " + triggerCompCode + " @changePopupList=\"" + popupMethodCode + "\" @blurChange=\"" + blurMethodCode + "\" :disabled=\"formType?disabled:(type=='look'?true:false)\"></xjr-input-number> \r\n");
                    StringBuilder inputConfig = new StringBuilder( "'title':'" + fieldLabel + "',placeholder : '请填写" + fieldLabel + "',  " +preLoadCode+ "defaultValue:\"" + defaultValue + "\"" + attrCode + "");
                    Map slot__ = MapUtils.getMap(field, "__slot__");
                    String append = MapUtils.getString(slot__, "append");
                    String prepend = MapUtils.getString(slot__, "prepend");
                    inputConfig.append(",\"prepend\": " + (StringUtils.isEmpty(prepend) ? "null" : "\"" + prepend + "\"") + ",\"append\": " + (StringUtils.isEmpty(append) ? "null" : "\"" + append + "\"") );
                    inputConfig.append(",isCapitalized:" + MapUtils.getBoolean(field, "isCapitalized", false));
                    inputConfig.append(",\"formId\":" + formId);
                    inputConfig.append(",\"table\":\"" + tableName + "\"");
                    inputConfig.append(",\"field\":\"" + fieldName + "\"");
                    inputConfig.append(",\"computation\":" + JSON.toJSONString(field.get("computationalConfiguration")));
                    inputConfig.append(",\"relative\":" + JSON.toJSONString(field.get("relativeComObject")));
                    inputConfig.append(",type:\"" + MapUtils.getString(field, "type") + "\"");
                    if (MapUtils.getBoolean(field, "isTax", false)) {
                        inputConfig.append(",taxRate:" + MapUtils.getString(field, "taxRate") + "");
                    }
                    configList.add(fieldName + "Config : {" + inputConfig.toString() + triggerConfigCode + "},");
                    importList.add("import xjrInputNumber from \"@/components/form/Input/InputNumber.vue\"");
                    componentList.add("xjrInputNumber");
                //密码
                } else if (StringUtils.equalsIgnoreCase(avueType, "password")) {
                    code.append(intentSpace + "           <xjr-password v-model=\"formData" + formDataTableName + tableIndexCode + "." + fieldName + "\"" + authCode + " :config=\"formJson." + subTableNameCode + fieldName + "Config\"" + triggerCompCode + " :disabled=\"formType?disabled:(type=='look'?true:false)\"></xjr-password> \r\n");
                    Map slot = MapUtils.getMap(field, "__slot__");
                    configList.add(fieldName + "Config : { 'title':'" + fieldLabel + "',placeholder : '请填写" + fieldLabel + "',  " +preLoadCode+ " maxlength:" + MapUtils.getInteger(field, "maxlength") + ",prepend:\"" + MapUtils.getString(slot, "prepend") + "\",append:\"" + MapUtils.getString(slot, "append") + "\",prefixIcon:" + MapUtils.getString(field, "refix-icon") + ",value:\"" + defaultValue + "\", formId:" + formId + attrCode + triggerConfigCode + "},");
                    importList.add("import xjrPassword from \"@/components/form/Input/Password.vue\"");
                    componentList.add("xjrPassword");
                //编码
                } else if (StringUtils.equalsIgnoreCase(avueType, "autoCode")) {
                    code.append(intentSpace + "           <xjr-automatic-coding v-model=\"formData" + formDataTableName + tableIndexCode + "." + fieldName + "\"" + authCode + " :config=\"formJson." + subTableNameCode + fieldName + "Config\"" + triggerCompCode + "></xjr-automatic-coding> \r\n");
                    configList.add(fieldName + "Config : { 'title':'" + fieldLabel + "',placeholder : '请填写" + fieldLabel + "',  " +preLoadCode+ " autoCodeRule:'" + MapUtils.getString(config, "autoCodeRule") + "',value:\"" + defaultValue + "\", formId:" + formId + attrCode + triggerConfigCode + "},");
                    importList.add("import xjrAutomaticCoding from \"@/components/form/Input/AutomaticCoding.vue\"");
                    componentList.add("xjrAutomaticCoding");
                }
                break;
            //分割线
            case "el-divider":
                code.append(intentSpace + "           <view class=\"bg-white padding-tb\"> \r\n");
                code.append(intentSpace + "               <view :style=\"{borderBottom:'1px solid #ccc',marginTop:formJson.line" + formId +"SplitLineConfig.top+'px',\r\n");
                code.append(intentSpace + "               marginBottom:formJson.line" + formId +"SplitLineConfig.bottom+'px'}\"></view>\r\n");
                code.append(intentSpace + "           </view>\r\n");
                configList.add("line" + formId + "SplitLineConfig : { top:" + MapUtils.getInteger(config, "top") + ",bottom : " + MapUtils.getInteger(config, "bottom") + ",value:\"" + defaultValue + "\", formId:" + formId + attrCode + "},");
                break;
            //意见簿
            case "xjr-opinion-comonent":
                code.append(intentSpace + "           <view class=\"bg-white padding-bottom-sm border-bottom\" v-if=\"formType\"> \r\n");
                code.append(intentSpace + "               <FormItem :label=\"formJson." + MapUtils.getString(field, "__vModel__") + "Config.title\" :verify=\"false\">\r\n");
                code.append(intentSpace + "                   <block slot=\"item\">\r\n");
                code.append(intentSpace + "                       <xjr-opinion :value=\"JSON.parse(formData" + (isSingleTable ? StringPool.EMPTY : "." + mainTableName) + "." + MapUtils.getString(field, "__vModel__") +")\"></xjr-opinion>\r\n");
                code.append(intentSpace + "                   </block>\r\n");
                code.append(intentSpace + "               </FormItem>\r\n");
                code.append(intentSpace + "           </view>\r\n");
                configList.add(MapUtils.getString(field, "__vModel__") + "Config : { 'title':'" + fieldLabel + "',placeholder : '请填写" + fieldLabel + "',  " +preLoadCode+ "type:'" + MapUtils.getString(field, "__type__") + "',value:\"" + defaultValue + "\", formId:" + formId + attrCode + "},");
                importList.add("import FormItem from \"@/components/workflow/FormItem.vue\"");
                importList.add("import xjrOpinion from \"@/components/form/Opinion/Opinion.vue\";");
                componentList.add("FormItem");
                componentList.add("xjrOpinion");
                break;
            //计数器
            case "el-input-number":
                code.append(intentSpace + "           <xjr-number v-model=\"formData" + formDataTableName + tableIndexCode + "." + fieldName + "\"" + authCode + " :config=\"formJson." + subTableNameCode + fieldName + "Config\"" + triggerCompCode + " :disabled=\"formType?disabled:(type=='look'?true:false)\"></xjr-number> \r\n");
                Integer precision = MapUtils.getInteger(field, "precision");
                configList.add(fieldName + "Config : { 'title':'" + fieldLabel + "',placeholder : '请填写" + fieldLabel + "',  " +preLoadCode+ " maxlength:" + MapUtils.getInteger(field, "maxlength") + (precision == null ? StringPool.EMPTY : (",precision: " + precision)) + ",step:" + MapUtils.getInteger(field, "step", 1) + ",stepStrictly:" + MapUtils.getBoolean(field, "step-strictly", false) + ",min:" + MapUtils.getString(field, "min", "-Infinity") + ",max:" + MapUtils.getString(field, "max", "Infinity") + ",value:" + (defaultValue == null ? "null" : "\"" + defaultValue + "\"") + ", \"formId\":" + formId + attrCode + triggerConfigCode + "},");
                importList.add("import xjrNumber from \"@/components/form/Input/Number.vue\"");
                componentList.add("xjrNumber");
                break;
            //单选
            case "el-radio-group":
                code.append(intentSpace + "           <xjr-radio v-model=\"formData" + formDataTableName + tableIndexCode + "." + fieldName + "\"" + authCode + " :config=\"formJson." + subTableNameCode + fieldName + "Config\"" + triggerCompCode + " :disabled=\"formType?disabled:(type=='look'?true:false)\"></xjr-radio> \r\n");
                configList.add(fieldName + "Config : { 'title':'" + fieldLabel + "',placeholder : '请填写" + fieldLabel + "',  " +preLoadCode+ "dataSource:'" + dataSource + "',dataItem:'" + dataItem + "',showfield:'" + MapUtils.getString(config, "showField") + "',savefield:'" + MapUtils.getString(config, "saveField") + "',value:\"" + defaultValue + "\", formId:" + formId + attrCode + apiCode + triggerConfigCode + "},");
                importList.add("import xjrRadio from \"@/components/form/Radio/RadioDialog.vue\"");
                componentList.add("xjrRadio");
                break;
            //颜色选择
            case "el-color-picker":
                code.append(intentSpace + "           <xjr-color-picker v-model=\"formData" + formDataTableName + tableIndexCode + "." + fieldName + "\"" + authCode + " :colorConfig=\"formJson." + subTableNameCode + fieldName + "Config\"" + triggerCompCode + " :disabled=\"formType?disabled:(type=='look'?true:false)\"></xjr-color-picker> \r\n");
                configList.add(fieldName + "Config : { 'title':'" + fieldLabel + "',placeholder : '请填写" + fieldLabel + "',  " +preLoadCode+ "verify:" + required + ",color:'" + defaultValue + "',type:\"colorpicker\", formId:" + formId + attrCode + triggerConfigCode + "},");
                importList.add("import xjrColorPicker from \"@/components/t-color-picker/ColorPicker.vue\"");
                componentList.add("xjrColorPicker");
                break;
            //滑块
            case "el-slider":
                code.append(intentSpace + "           <xjr-slider v-model=\"formData" + formDataTableName + tableIndexCode + "." + fieldName + "\"" + authCode + " :config=\"formJson." + subTableNameCode + fieldName + "Config\"" + triggerCompCode + " :disabled=\"formType?disabled:(type=='look'?true:false)\"></xjr-slider> \r\n");
                configList.add(fieldName + "Config : { 'title':'" + fieldLabel + "',value:\"" + defaultValue + "\",  " +preLoadCode+ " formId:" + formId + attrCode + triggerConfigCode + "},");
                importList.add("import xjrSlider from \"@/components/form/Slider/Slider.vue\"");
                componentList.add("xjrSlider");
                break;
            //开关
            case "el-switch":
                code.append(intentSpace + "           <xjr-switch v-model=\"formData" + formDataTableName + tableIndexCode + "." + fieldName + "\"" + authCode + " :swithConfig=\"formJson." + subTableNameCode + fieldName + "Config\"" + triggerCompCode + " :disabled=\"formType?disabled:(type=='look'?true:false)\"></xjr-switch> \r\n");
                configList.add(fieldName + "Config : { 'title':'" + fieldLabel + "',color:\"" + MapUtils.getString(field, "active-color") + "\",  " +preLoadCode+ "value:\"" + defaultValue + "\", active:" + MapUtils.getInteger(field, "active-value") +",inactive:" + MapUtils.getInteger(field, "inactive-value") + ", formId:" + formId + attrCode + triggerConfigCode + "},");
                importList.add("import xjrSwitch from \"@/components/form/Switch/Switch.vue\"");
                componentList.add("xjrSwitch");
                break;
            //评分
            case "el-rate":
                code.append(intentSpace + "           <xjr-star v-model=\"formData" + formDataTableName + tableIndexCode + "." + fieldName + "\"" + authCode + " :starConfig=\"formJson." + subTableNameCode + fieldName + "Config\"" + triggerCompCode + " :disabled=\"formType?disabled:(type=='look'?true:false)\"></xjr-star> \r\n");
                configList.add(fieldName + "Config : { 'title':'" + fieldLabel + "',curStarNum:" + defaultValue + ",  " +preLoadCode+ "maxStar:" + MapUtils.getInteger(field, "max") + ",showText:" + MapUtils.getBoolean(field, "show-text",false) + ",showScore:" + MapUtils.getBoolean(field, "show-score",false) + ",defaultStar:" + defaultValue + ", formId:" + formId + attrCode + triggerConfigCode + "},");
                importList.add("import xjrStar from \"@/components/form/Star/Star.vue\"");
                componentList.add("xjrStar");
                break;
            //多选框组
            case "el-checkbox-group":
                code.append(intentSpace + "           <xjr-check-box v-model=\"formData" + formDataTableName + tableIndexCode + "." + fieldName + "\"" + authCode + " :config=\"formJson." + subTableNameCode + fieldName + "Config\"" + triggerCompCode + " :disabled=\"formType?disabled:(type=='look'?true:false)\"></xjr-check-box> \r\n");
                configList.add(fieldName + "Config : { 'title':'" + fieldLabel + "',placeholder : '请选择" + fieldLabel + "',  " +preLoadCode+ "dataSource:'" + dataSource + "',dataItem:'" + dataItem + "',showfield:'" + MapUtils.getString(config, "showField") + "',savefield:'" + MapUtils.getString(config, "saveField") + "',value:\"" + defaultValue + "\", formId:" + formId + attrCode + apiCode + triggerConfigCode + "},");
                importList.add("import xjrCheckBox from \"@/components/form/Checked/CheckedDialog.vue\"");
                componentList.add("xjrCheckBox");
                break;
            case "el-select":
                //下拉选择
                if (StringUtils.equalsIgnoreCase(avueType, "select")) {
                    code.append(intentSpace + "           <xjr-select v-model=\"formData" + formDataTableName + tableIndexCode + "." + fieldName + "\"" + authCode + " :selectConfig=\"formJson." + subTableNameCode + fieldName + "Config\"" + triggerCompCode + " :disabled=\"formType?disabled:(type=='look'?true:false)\"></xjr-select> \r\n");
                    configList.add(fieldName + "Config : { 'title':'" + fieldLabel + "',placeholder : '请选择" + fieldLabel + "',  " +preLoadCode+ "dataSource:'" + dataSource + "',dataItem:'" + dataItem + "',showfield:'" + MapUtils.getString(config, "showField") + "',savefield:'" + MapUtils.getString(config, "saveField") + "',value:\"" + defaultValue + "\", formId:" + formId + attrCode + apiCode + triggerConfigCode + "},");
                    importList.add("import xjrSelect from \"@/components/form/Select/Select.vue\"");
                    componentList.add("xjrSelect");
                //联想下拉
                } else if (StringUtils.equalsIgnoreCase(avueType, "asso-select")) {
                    String subIndexCode = isSubTable ? " :childIndex=\"childIndex\"" : StringPool.EMPTY;
                    String popupMethod = isSubTable ? "changeTableAssociative" : "changeAssociative";
                    code.append(intentSpace + "           <xjr-asso-select v-model=\"formData" + formDataTableName + tableIndexCode + "." + fieldName + "\"" + authCode + " :config=\"formJson." + subTableNameCode + fieldName + "Config\"" + subIndexCode + triggerCompCode +" @changePopupList=\"" + popupMethod + "\" :disabled=\"formType?disabled:(type=='look'?true:false)\"></xjr-asso-select>\r\n");
                    configList.add(fieldName + "Config : { 'title':'" + fieldLabel + "',placeholder : '请填写" + fieldLabel + "',  " +preLoadCode+ "type:'assoSelect',autoBindFields:" + JSON.toJSONString(MapUtils.getString(config, "autoBindFields")) + ",isSingle:true,table:'" + tableName + "',dataSource:\"" + dataSource + "\",dataItem:\""
                            + dataItem + "\",showfield:'" + MapUtils.getString(config, "showField") + "',savefield:'" + MapUtils.getString(config, "saveField") + "',value:\"" + defaultValue + "\", formId:" + formId + attrCode + apiCode + triggerConfigCode + "},");
                    importList.add("import xjrAssoSelect from \"@/components/form/Select/AssoSelect.vue\"");
                    componentList.add("xjrAssoSelect");
                }

                break;
            case "el-date-picker":
                //日期
                String format = StringUtils.defaultIfBlank(getDateFormat(MapUtils.getString(field, "type")), MapUtils.getString(field, "format"));
                if (StringUtils.equalsIgnoreCase(avueType, "datetime")) {
                    code.append(intentSpace + "           <xjr-date-picker v-model=\"formData" + formDataTableName + tableIndexCode + "." + fieldName + "\"" + authCode + " :datePickerConfig=\"formJson." + subTableNameCode + fieldName + "Config\"" + triggerCompCode +" :disabled=\"formType?disabled:(type=='look'?true:false)\"></xjr-date-picker> \r\n");
                    configList.add(fieldName + "Config : { 'title':'" + fieldLabel + "',placeholder : '点击选择" + fieldLabel + "',  " +preLoadCode+ "value:\"" + defaultValue + "\", format:'" + format + "', formId:" + formId + attrCode + triggerConfigCode + "},");
                    importList.add("import xjrDatePicker from \"@/components/form/DatePicker/DatePicker.vue\"");
                    componentList.add("xjrDatePicker");
                //日期时间区间
                } else if (StringUtils.equalsIgnoreCase(avueType, "daterange")) {
                    String type = MapUtils.getString(field, "type");
                    if (StringUtil.equalsIgnoreCase(type, "monthrange")
                            || StringUtil.equalsIgnoreCase(type, "daterange")) {
                        String dateFormat = StringUtil.equalsIgnoreCase(type, "monthrange") ? "month" : "date";
                        code.append(intentSpace + "           <xjr-range-date v-model=\"formData" + formDataTableName + tableIndexCode + "." + fieldName + "\"" + authCode + " :datePickerConfig=\"formJson." + subTableNameCode + fieldName + "Config\"" + triggerCompCode +" :disabled=\"formType?disabled:(type=='look'?true:false)\"></xjr-range-date> \r\n");
                        configList.add(fieldName + "Config : { 'title':'" + fieldLabel + "',placeholder : '点击选择" + fieldLabel + "',  " +preLoadCode+ "value:\"" + handleListDefaultValue(defaultValue) + "\", format:'" + dateFormat + "', formId:" + formId + ", separator:'" + MapUtils.getString(field, "range-separator", StringPool.COMMA) + "'" + attrCode + triggerConfigCode + "},");
                        importList.add("import xjrRangeDate from \"@/components/form/DatePicker/rangeDate.vue\"");
                        componentList.add("xjrRangeDate");
                    } else {
                        code.append(intentSpace + "           <xjr-date-time-range-picker v-model=\"formData" + formDataTableName + tableIndexCode + "." + fieldName + "\"" + authCode + " :datetimePickerConfig=\"formJson." + subTableNameCode + fieldName + "Config\"" + triggerCompCode +" :disabled=\"formType?disabled:(type=='look'?true:false)\"></xjr-date-time-range-picker> \r\n");
                        configList.add(fieldName + "Config : { 'title':'" + fieldLabel + "',placeholder : '点击选择" + fieldLabel + "',  " +preLoadCode+ "value:\"" + handleListDefaultValue(defaultValue) + "\", format:'" + format + "', formId:" + formId + ", separator:'" + MapUtils.getString(field, "range-separator", StringPool.COMMA) + "'" + attrCode + triggerConfigCode + "},");
                        importList.add("import xjrDateTimeRangePicker from \"@/components/form/DateTimePicker/DateTimePicker.vue\"");
                        componentList.add("xjrDateTimeRangePicker");
                    }
                }
                break;
            case "el-time-picker":
                //时间选择
                if (StringUtils.equalsIgnoreCase(avueType, "time")) {
                    Map<String, Object> option = MapUtils.getMap(field, "picker-options");
                    code.append(intentSpace + "           <xjr-time-picker v-model=\"formData" + formDataTableName + tableIndexCode + "." + fieldName + "\"" + authCode + " :timePickerConfig=\"formJson." + subTableNameCode + fieldName + "Config\"" + triggerCompCode +" :disabled=\"formType?disabled:(type=='look'?true:false)\"></xjr-time-picker> \r\n");
                    configList.add(fieldName + "Config : { 'title':'" + fieldLabel + "',placeholder : '点击选择" + fieldLabel + "',  " +preLoadCode+ " format:'hh:ii:ss',value:\"" + defaultValue + "\", formId:" + formId + ",\"selectableRange\":\"" + MapUtils.getString(option, "selectableRange") + "\"" + attrCode + triggerConfigCode + "},");
                    importList.add("import xjrTimePicker from \"@/components/form/TimePicker/TimePicker.vue\"");
                    componentList.add("xjrTimePicker");
                //日期时间区间
                } else if (StringUtils.equalsIgnoreCase(avueType, "timerange")) {
                    code.append(intentSpace + "           <xjr-time-range v-model=\"formData" + formDataTableName + tableIndexCode + "." + fieldName + "\"" + authCode + " :timeRangeConfig=\"formJson." + subTableNameCode + fieldName + "Config\"" + triggerCompCode +" :disabled=\"formType?disabled:(type=='look'?true:false)\"></xjr-time-range> \r\n");
                    configList.add(fieldName + "Config : { 'title':'" + fieldLabel + "',placeholder : '点击选择" + fieldLabel + "',  " +preLoadCode+ "value:\"" + handleListDefaultValue(defaultValue) + "\", format:'hh:ii:ss', formId:" + formId + ", separator:'" + MapUtils.getString(field, "range-separator", StringPool.COMMA) + "'" + attrCode + triggerConfigCode + "},");
                    importList.add("import xjrTimeRange from \"@/components/form/TimePicker/TimeRange.vue\"");
                    componentList.add("xjrTimeRange");
                }
                break;
            //编辑器
            case "tinymce":
                code.append(intentSpace + "           <xjr-edit v-model=\"formData" + formDataTableName + tableIndexCode + "." + fieldName + "\"" + authCode + " :editConfig=\"formJson." + subTableNameCode + fieldName + "Config\"" + triggerCompCode +" :disabled=\"formType?disabled:(type=='look'?true:false)\"></xjr-edit> \r\n");
                configList.add(fieldName + "Config : { 'title':'" + fieldLabel + "',placeholder : '请填写" + fieldLabel + "',  " +preLoadCode+ "value:\"" + defaultValue + "\", height:" + MapUtils.getInteger(field, "height") + ", formId:" + formId + attrCode + triggerConfigCode + "},");
                importList.add("import xjrEdit from \"@/components/form/Editor/Editor.vue\"");
                componentList.add("xjrEdit");

                break;
            //上传文件
            case "el-upload":
                String listType = MapUtils.getString(field, "list-type");
                if (StringUtils.equalsIgnoreCase(listType, "picture-card")) {
                    code.append(intentSpace + "           <xjr-img-upload v-model=\"formData" + formDataTableName + tableIndexCode + "." + fieldName + "\"" + authCode + " :imgUpLoadConfig=\"formJson." + subTableNameCode + fieldName + "Config\"" + triggerCompCode +" :disabled=\"formType?disabled:(type=='look'?true:false)\"></xjr-img-upload> \r\n");
                    configList.add(fieldName + "Config : { 'title':'" + fieldLabel + "',placeholder : '" + MapUtils.getString(config, "buttonText") + "',  " +preLoadCode+ "imgLength:null,defaultValue:\"" + defaultValue + "\", formId:" + formId + attrCode + triggerConfigCode + "},");
                    importList.add("import xjrImgUpload from \"@/components/form/Img/Img.vue\"");
                    componentList.add("xjrImgUpload");
                } else {
                    code.append(intentSpace + "           <xjr-file-upload v-model=\"formData" + formDataTableName + tableIndexCode + "." + fieldName + "\"" + authCode + " :fileUploadConfig=\"formJson." + subTableNameCode + fieldName + "Config\"" + triggerCompCode +" :disabled=\"formType?disabled:(type=='look'?true:false)\"></xjr-file-upload> \r\n");
                    configList.add(fieldName + "Config : { 'title':'" + fieldLabel + "',placeholder : '" + MapUtils.getString(config, "buttonText") + "',  " +preLoadCode+ "defaultValue:\"" + defaultValue + "\", formId:" + formId + attrCode + triggerConfigCode + "},");
                    importList.add("import xjrFileUpload from \"@/components/form/RenderCustomForm/FileUpload.vue\"");
                    componentList.add("xjrFileUpload");
                }
                break;
            //图片
            case "el-image":
                code.append(intentSpace + "           <view class=\"bg-white item-box padding-bottom-sm border-bottom\">");
                code.append(intentSpace + "               <FormItem :label=\"formJson." + subTableNameCode + fieldName + "Config.title\" :verify=\"false\">");
                code.append(intentSpace + "                   <block slot=\"item\">");
                code.append(intentSpace + "                       <xjr-input-img class=\"img\" v-model=\"formData" + formDataTableName + tableIndexCode + "." + fieldName + "\"" + authCode + " :srcUrl=\"formJson." + subTableNameCode + fieldName + "Config.value\"/>");
                code.append(intentSpace + "                   </block>");
                code.append(intentSpace + "               </FormItem>");
                code.append(intentSpace + "           </view>");
                configList.add(fieldName + "Config : { 'title':'" + fieldLabel + "',value : '" + defaultValue + "',  " +preLoadCode+ " formId:" + formId + attrCode + "},");
                importList.add("import xjrInputImg from \"@/components/form/Input/Img.vue\"");
                importList.add("import FormItem from \"@/components/workflow/FormItem.vue\"");
                componentList.add("xjrInputImg");
                componentList.add("FormItem");

                break;
            //信息体
            case "avue-information-body":
                code.append(intentSpace + "           <xjr-information-body v-model=\"formData" + formDataTableName + tableIndexCode + "." + fieldName + "\"" + authCode + " :config=\"formJson." + subTableNameCode + fieldName + "Config\"" + triggerCompCode +" :disabled=\"formType?disabled:(type=='look'?true:false)\"></xjr-information-body> \r\n");
                configList.add(fieldName + "Config : { 'title':'" + fieldLabel + "',infoType : '" + MapUtils.getString(field, "infoType") + "',  " +preLoadCode+ "value:\"" + defaultValue + "\", formId:" + formId + ",secondaryEditing:" + MapUtils.getBoolean(config, "whetherToRebindSecondaryEditing") + attrCode + triggerConfigCode + "},");
                importList.add("import xjrInformationBody from \"@/components/form/Organization/InformationBody.vue\"");
                componentList.add("xjrInformationBody");
                break;
            //公司、部门
            case "avue-input-tree":
                String type__ = MapUtils.getString(field, "__type__");
                configList.add(fieldName + "Config : { 'title':'" + fieldLabel + "',infoType : '" + type__ + "',  " +preLoadCode+ "value:\"" + defaultValue + "\", formId:" + formId + attrCode + triggerConfigCode + "},");
                if (StringUtils.equalsIgnoreCase(type__, "company")) {
                    code.append(intentSpace + "           <xjr-company v-model=\"formData" + formDataTableName + tableIndexCode + "." + fieldName + "\"" + authCode + " :config=\"formJson." + subTableNameCode + fieldName + "Config\"" + triggerCompCode +" :disabled=\"formType?disabled:(type=='look'?true:false)\"></xjr-company> \r\n");
                    importList.add("import xjrCompany from \"@/components/form/Organization/Company.vue\"");
                    componentList.add("xjrCompany");
                } else if(StringUtils.equalsIgnoreCase(type__, "department")) {
                    code.append(intentSpace + "           <xjr-department v-model=\"formData" + formDataTableName + tableIndexCode + "." + fieldName + "\"" + authCode + " :config=\"formJson." + subTableNameCode + fieldName + "Config\"" + triggerCompCode +" :disabled=\"formType?disabled:(type=='look'?true:false)\"></xjr-department> \r\n");
                    importList.add("import xjrDepartment from \"@/components/form/Organization/Department.vue\"");
                    componentList.add("xjrDepartment");
                }
                break;
            //人员
            case "xjr-select-user":
                code.append(intentSpace + "           <xjr-user v-model=\"formData" + formDataTableName + tableIndexCode + "." + fieldName + "\"" + authCode + " :config=\"formJson." + subTableNameCode + fieldName + "Config\"" + triggerCompCode +" :disabled=\"formType?disabled:(type=='look'?true:false)\"></xjr-user> \r\n");
                configList.add(fieldName + "Config : { 'title':'" + fieldLabel + "',infoType : '" + MapUtils.getString(field, "__type__") + "',  " +preLoadCode+ "value:\"" + defaultValue + "\", formId:" + formId + attrCode + triggerConfigCode + "},");
                importList.add("import xjrUser from \"@/components/form/Organization/User.vue\"");
                componentList.add("xjrUser");
                break;
            //行政区域
            case "avue-select-area":
                code.append(intentSpace + "           <xjr-area v-model=\"formData" + formDataTableName + tableIndexCode + "." + fieldName + "\"" + authCode + " :config=\"formJson." + subTableNameCode + fieldName + "Config\"" + triggerCompCode + " :disabled=\"formType?disabled:(type=='look'?true:false)\"></xjr-area> \r\n");
                configList.add(fieldName + "Config : { 'title':'" + fieldLabel + "',placeholder : '请选择" + fieldLabel + "',  " +preLoadCode+ "value:\"" + defaultValue + "\", formId:" + formId + attrCode + triggerConfigCode + "},");
                importList.add("import xjrArea from \"@/components/form/Area/Area.vue\"");
                componentList.add("xjrArea");
                break;
            case "el-mutiple-input":
                //联想弹层
                if (StringUtils.equalsIgnoreCase(avueType, "asso-popup")) {
                    String subIndexCode = isSubTable ? " :childIndex=\"childIndex\"" : StringPool.EMPTY;
                    String popupMethod = isSubTable ? "changeTableAssociative" : "changeAssociative";
                    code.append(intentSpace + "           <xjr-associative-elastic-layer v-model=\"formData" + formDataTableName + tableIndexCode + "." + fieldName + "\"" + authCode + " :inputConfig=\"formJson." + subTableNameCode + fieldName + "Config\"" + subIndexCode + triggerCompCode + " @changePopupList=\"" + popupMethod + "\" :disabled=\"formType?disabled:(type=='look'?true:false)\"></xjr-associative-elastic-layer>");
                    configList.add(fieldName + "Config : { 'title':'" + fieldLabel + "',placeholder : '请填写" + fieldLabel + "',  " +preLoadCode+ "type:'assoPopup',autoBindFields:" + JSON.toJSONString(MapUtils.getString(config, "autoBindFields")) + ",isSingle:true,table:'" + tableName + "',dataSource:\"" + dataSource + "\",dataItem:\""
                            + dataItem + "\",showfield:'" + MapUtils.getString(config, "showField") + "',savefield:'" + MapUtils.getString(config, "saveField") + "',value:\"" + defaultValue + "\", formId:" + formId + attrCode + apiCode + triggerConfigCode + "},");
                    importList.add("import xjrAssociativeElasticLayer from \"@/components/form/AssociativeElasticLayer/Input.vue\"");
                    componentList.add("xjrAssociativeElasticLayer");
                //多选弹层
                } else if(StringUtils.equalsIgnoreCase(avueType, "mutiple-popup")) {
                    code.append(intentSpace + "           <xjr-mutiple-select-layer v-model=\"formData" + formDataTableName + tableIndexCode + "." + fieldName + "\"" + authCode + " :inputConfig=\"formJson." + subTableNameCode + fieldName + "Config\"" + triggerCompCode + " :disabled=\"formType?disabled:(type=='look'?true:false)\"></xjr-mutiple-select-layer>");
                    configList.add(fieldName + "Config : { 'title':'" + fieldLabel + "',placeholder : '请填写" + fieldLabel + "',  " +preLoadCode+ "autoBindFields:" + JSON.toJSONString(MapUtils.getString(config, "autoBindFields")) + "" +
                            ",isSingle:false,table:'" + tableName + "',dataSource:\"" + dataSource + "\",dataItem:\""
                            + dataItem + "\",showfield:'" + MapUtils.getString(config, "showField") + "',savefield:'" + MapUtils.getString(config, "saveField") + "',value:\"" + defaultValue + "\", formId:" + formId + attrCode + apiCode + triggerConfigCode + "},");
                    importList.add("import xjrMutipleSelectLayer from \"@/components/form/AssociativeElasticLayer/Mutiple.vue\"");
                    componentList.add("xjrMutipleSelectLayer");
                }
                break;
            //级联选择
            case "xjr-cascader":
                code.append(intentSpace + "           <xjr-cascader v-model=\"formData" + formDataTableName + tableIndexCode + "." + fieldName + "\"" + authCode + " :inputConfig=\"formJson." + subTableNameCode + fieldName + "Config\"" + triggerCompCode + " :disabled=\"formType?disabled:(type=='look'?true:false)\"></xjr-cascader> \r\n");
                configList.add(fieldName + "Config : { 'title':'" + fieldLabel + "',placeholder : '请选择" + fieldLabel + "',  " +preLoadCode+ "settings:" + JSON.toJSONString(MapUtils.getObject(config, "settings")) + ",separator:'" + MapUtils.getString(field, "separator") + "',showAllLevels:" + MapUtils.getBoolean(field,"show-all-levels") + ",value:\"" + defaultValue + "\", formId:" + formId + attrCode + ", checkStrictly:" + MapUtils.getBoolean(field, "checkStrictly", false) + triggerConfigCode + "},");
                importList.add("import xjrCascader from \"@/components/form/cascader/cascader.vue\"");
                componentList.add("xjrCascader");
                break;
            case "avue-custom-button":
                code.append(intentSpace + "           <xjr-custom-button :config=\"formJson." + subTableNameCode + fieldName + "Config\" @customButtonClick=\"customButtonClick\"" + triggerCompCode + "></xjr-custom-button> \r\n");
                configList.add(fieldName + "Config : { 'title':'" + fieldLabel + "',  " +preLoadCode+ "showLabel : " + MapUtils.getBoolean(config, "showLabel") + ",btnWidth:" + MapUtils.getInteger(field, "btnWidth") + ",btnHeight:" + MapUtils.getInteger(field, "btnHeight") + ",content:\"" + MapUtils.getString(field,"content") + "\",\"prefix-icon\":\"" + MapUtils.getString(field,"prefix-icon") + "\", \"suffix-icon\":\"" + MapUtils.getString(field,"suffix-icon") + "\"" + triggerConfigCode + "},");
                importList.add("import xjrCustomButton from \"@/components/form/button/CustomButton.vue\"");
                componentList.add("xjrCustomButton");
                break;
        }
    }

    public static void writeAppViewCode(String pk, CodeSchemaDto codeSchemaDto, XjrAppFunction appFunction, GlobalConfigProperties buildCodeProperties) throws Exception {
        BaseInfoDto baseInfoDto = codeSchemaDto.getBaseInfoDto();
        String moduleName = baseInfoDto.getName();
        String moduleLabel = codeSchemaDto.getModuleDataDto().getFullName();
        String appProjectPath = buildCodeProperties.getAppProjectPath();
        String appCodePath = baseInfoDto.getAppDirectory();
        File dir = new File(appProjectPath + File.separator + appCodePath);
        if (!dir.exists()) {
            dir.mkdirs();
        }
        //移动端列表页代码
        String listViewCode = genListViewCode(pk, codeSchemaDto.getColDataDto(), codeSchemaDto.getQueryDataDtoList(), codeSchemaDto.getFormDataDtoList(), baseInfoDto);
        FileOutputStream appListFos = new FileOutputStream(dir + File.separator + moduleName + "List.vue");
        IoUtil.write(appListFos, true, listViewCode.getBytes("UTF-8"));
        //移动端表单也代码
        String formViewCode = genFormViewCode(moduleLabel, codeSchemaDto.getDbTableDtoList(), codeSchemaDto.getFormDataDtoList(), baseInfoDto, codeSchemaDto.getEventData());
        FileOutputStream appFormFos = new FileOutputStream(dir + File.separator + moduleName + "Form.vue");
        IoUtil.write(appFormFos, true, formViewCode.getBytes("UTF-8"));

        // 菜单信息保存
        String outputArea = MapUtils.getString(baseInfoDto.getOutputArea(), "F_ItemValue");
        ModuleDataDto moduleDataDto = codeSchemaDto.getModuleDataDto();
        appFunction.setIcon(moduleDataDto.getAppIcon());
        appFunction.setName(moduleDataDto.getFullName());
        appFunction.setSortCode(Integer.valueOf(moduleDataDto.getAppSortCode()));
        appFunction.setUrl("customercode/" + outputArea + "/" + moduleName + "List");
        appFunction.setType(moduleDataDto.getAppCataLog());
        appFunction.setIsSystem(1);

        // 修改app配置文件
        // pages.json
        String pageJsonPath = buildCodeProperties.getAppProjectPath() + File.separator + "pages.json";
        String pageJsonText = IoUtil.read(new FileInputStream(pageJsonPath), "UTF-8" );
        JSONObject pageJson = JSONObject.parseObject(pageJsonText);
        JSONArray pages = pageJson.getJSONArray("pages" );
        JSONObject listJson = new JSONObject();
        listJson.put("path", appCodePath + "/" + moduleName + "List");
        JSONObject listStyle = new JSONObject();
        listStyle.put("navigationBarTitleText", moduleLabel);
        listJson.put("style", listStyle);
        pages.add(listJson);
        // Index.vue
        String indexPath = buildCodeProperties.getAppProjectPath() + File.separator + "components" + File.separator + "form" + File.separator + "RenderSystemForm" + File.separator + "Index.vue";
        List<String> lineCodeList = IoUtil.readLines(new FileInputStream(indexPath), "UTF-8", new ArrayList<>());
        StringBuilder newIndexText = new StringBuilder();
        boolean existWarningCode = false;
        for (String lineCode : lineCodeList) {

            boolean isHtmlCode = StringUtils.containsIgnoreCase(lineCode, "<!--html-->");
            if (isHtmlCode) {
                newIndexText.append("       <" + moduleName + " v-if=\"componentName=='" + StringUtils.lowerCase(moduleName) + "'\" :formType=\"formType\" :controlType=\"controlType\" :formModels=\"formModels\" @changeSystemValue=\"changeSystemValue\" @defaultSystemValue=\"defaultSystemValue\" :disabled=\"disabled\"></" + moduleName + ">");
                newIndexText.append(System.lineSeparator());
                newIndexText.append("       <view v-else class=\"text-center text-c\">请检查表单文件是否存在</view>");
                newIndexText.append(System.lineSeparator());
            } else if (StringUtils.containsIgnoreCase(lineCode, "//script")) {
                newIndexText.append("import " + moduleName + " from \"" + appCodePath + "/" + moduleName + "Form.vue\";" + System.lineSeparator());
                newIndexText.append(System.lineSeparator());
            } else if (StringUtils.containsIgnoreCase(lineCode, "//components")) {
                newIndexText.append("       " + moduleName + "," + System.lineSeparator());
                newIndexText.append(System.lineSeparator());
            }
            boolean containsCheckCode = StringUtil.containsAnyIgnoreCase(lineCode, "<view v-else class=\"text-center text-c\">请检查表单文件是否存在</view>");
            if (!isHtmlCode && containsCheckCode) {
                continue;
            }
            newIndexText.append(lineCode);
            newIndexText.append(System.lineSeparator());
        }
        IoUtil.writeUtf8(new FileOutputStream(indexPath), true, newIndexText.toString());

        JSONObject formJson = new JSONObject();
        JSONObject formStyle = new JSONObject();
        formStyle.put("navigationStyle", "custom");
        formStyle.put("navigationBarTitleText", moduleLabel);
        formJson.put("style", formStyle);
        formJson.put("path", appCodePath + "/" + moduleName + "Form");
        pages.add(formJson);

        String pageJsonStr = JSON.toJSONString(pageJson, SerializerFeature.DisableCircularReferenceDetect);
        com.xjrsoft.core.tool.utils.IoUtil.write(JsonFormatUtil.formatJson(pageJsonStr), new FileOutputStream(pageJsonPath), Charset.forName("UTF-8"));
    }

    private static Map<String, Object> findFieldConfig(List<Map<String, Object>> fieldList, String findFieldName) {
        if (CollectionUtil.isNotEmpty(fieldList)) {
            for (Map<String, Object> field : fieldList) {
                Map<String, Object> config = MapUtils.getMap(field, FormConstants.CONFIG);
                String componentName = MapUtils.getString(config, "componentName");
                if (StringUtil.equalsIgnoreCase(componentName, "avue-tabs")) {
                    Map<String, List<Map<String, Object>>> childrenObj = MapUtils.getMap(config, "childrenObj");
                    for (List<Map<String, Object>> tabFieldList : childrenObj.values()) {
                        Map<String, Object> fieldConfig = findFieldConfig(tabFieldList, findFieldName);
                        if (fieldConfig != null) {
                            return fieldConfig;
                        }
                    }
                } else {
                    if (StringUtil.equalsIgnoreCase(MapUtils.getString(config, FormConstants.BIND_TABLE_FIELD), findFieldName)) {
                        return field;
                    }
                }

            }
        }
        return null;
    }

    private static String getDataSourceByType(String dataType) {
        String dataSource = StringPool.EMPTY;
        if (!StringUtil.isEmpty(dataType)) {
            switch (dataType) {
                case "dataSource":
                    dataSource = "0";
                    break;
                case "dataItem":
                    dataSource = "1";
                    break;
                case "dataSql":
                    dataSource = "2";
                    break;
                case "dataApi":
                    dataSource = "3";
            }
        }
        return dataSource;
    }

    private static String getDataItem(Map<String, Object> config, String dataSource) {
        String dataItem = StringPool.EMPTY;
        if (!StringUtil.isEmpty(dataSource)) {
            switch (dataSource) {
                case "0":
                    dataItem = MapUtils.getString(config, "dataSource");
                    break;
                case "1":
                    dataItem = MapUtils.getString(config, "dataItem");
                    break;
                case "2":
                    dataItem = MapUtils.getString(config, "database");
                    break;
            }
        }
        return dataItem;
    }

    private static String handleListDefaultValue(Object defaultValue) {
        StringBuilder multiStr = new StringBuilder();
        if (defaultValue instanceof Collection) {
            Collection multiValues = (Collection) defaultValue;
            int index = 0;
            for (Object value : multiValues) {
                if (StringUtil.isEmpty(value)) {
                    continue;
                }
                if (index > 0) {
                    multiStr.append(StringPool.COMMA);
                }
                multiStr.append(value);
                index++;
            }
        }
        return multiStr.toString();
    }

    private static String getDateFormat(String type) {
        String format = StringPool.EMPTY;
        switch (StringUtils.lowerCase(type)) {
            case "date":
            case "daterange":
                format = "yyyy-mm-dd";
                break;
            case "month":
            case "monthrange":
                format = "yyyy-mm";
                break;
            case "datetime":
            case "datetimerange":
                format = "yyyy-mm-dd hh:ii:ss";
                break;
            case "week":
                format = "yyyy 第 WW 周";
                break;
        }
        return format;
    }
}
